Skip to content
  • 0 Votes
    2 Posts
    199 Views
    C

    You should call QStyledItemDelegate::paint function inside yours QStyledItemDelegate derived class before painting of icons and text:

    void IconsRenderItemDelegate::paint(QPainter *painter,
    const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    QStyledItemDelegate::paint(painter, options, index);

    // Draw somethig
    }

  • 0 Votes
    5 Posts
    319 Views
    EmrecpE

    Can anyone share sample code for qlistwidget or qlistview?

  • -1 Votes
    7 Posts
    932 Views
    Christian EhrlicherC

    Please take a look at your post above - do you really think we can read something meaningful out of it. Please use the <code> - tags to make it more readable and reduce your code as much as possible so only the problem and nothing else is in there.

  • 0 Votes
    5 Posts
    378 Views
    JonBJ

    @charry
    Yes, you are normally supposed to double-click to edit a cell (one click to select the cell, double-click to edit the cell).

    If you want single-click to edit, you should look at, say, QTableView::setEditTriggers(QAbstractItemView::AllEditTriggers). See if one of those values do what you want? If not, have a read through e.g. https://stackoverflow.com/questions/18831242/qt-start-editing-of-cell-after-one-click, there are other possibilities there. Or further hits via Google qtableview click edit.

  • 0 Votes
    6 Posts
    1k Views
    mrjjM

    @sailord
    So it did use SizeHint but it was just returning too small value ?
    Super :)

  • 0 Votes
    4 Posts
    1k Views
    D

    In case anyone comes across this in a search, I was able to solve the problem by manipulating the selection in the class member function selectionChanged():

    https://bazaar.launchpad.net/~dlynch3/rapid/zeromq_pyqt/revision/1178#raphodo/thumbnaildisplay.py

    Perhaps that was always the best way to do it.

  • 0 Votes
    5 Posts
    3k Views
    S

    Thanks @SeitsemaN for this solution,
    *{outline: none;}

    This works well. I wasted like 8hrs on this.

  • 0 Votes
    4 Posts
    422 Views
    JonBJ

    @rahi444
    I don't claim to understand why you want to do this. However, does the example (teh accepted solution to it) in, say, https://stackoverflow.com/questions/36778577/qstyleditemdelegate-how-to-make-checkbox-button-to-change-its-state-on-click give you what you need? It's using https://doc.qt.io/qt-5/qstyleditemdelegate.html#editorEvent to access the widget's state in an event. Seems a bit low-level to me, but maybe that's what you do....?

    Otherwise, I know the editor arranges to store the widget's value via editor widget's user property, see https://doc.qt.io/qt-5/qstyleditemdelegate.html#setModelData itself. Can you leverage that without actually calling setModelData()?

    Finally, https://doc.qt.io/qt-5/qstyleditemdelegate.html#createEditor returns the widget created for doing the editing. Can you put your own slots/call functions on that to recognise when it's edited and retrieve its value directly?

    If all else fails, what about looking at the source of the setModelData() method you do not want to use in page https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qstyleditemdelegate.cpp.html ? You can see there what it does (looks pretty simple), and decide what you want to do compared to that, since you don't want to call it yourself for whatever reason.

  • 0 Votes
    2 Posts
    513 Views
    D

    Yo

    It appears that I was almost there... just need to create a proper drag!

    def initializeDrag(self, event, option, index): self.dragInitialized = True print("Drag initialized!") drag = QDrag(self) mim = QMimeData() mim.setText("yoyoyooy") drag.setMimeData(mim) val = drag.exec_() print("Return drag val : ", val) self.dragInitialized = False

    Once thats made, I then have to handle dragEnterEvent on QTreeView and then pass it to proper function from there... yay!

  • 0 Votes
    3 Posts
    2k Views
    D

    @mrjj I'm not getting any move/hover events in that function.

    I don't edit anything yet to get it I think. I'm drawing 3 rects in paint() function and now I'd like to highlight each rect when mouse hover over it.

    EDIT. it looks like I had to view.setMouseTracking(True) to get the event in delegate o.O

    But it does not fire on mouse enter/leave action sigh. :D

  • 0 Votes
    3 Posts
    308 Views
    D

    @sgaist

    Hey, sorry for slow reply. You got me thinking about the issue! I initially was taking const QStyleOptionViewItem &option - option.rect - and creating my checkbox from it. But I never checked if that rect had any width/height in itself... I did a check now, and if the width of the rect is less than the width of my checkbox then I don't paint it! :D I should probably also check the position... but meh. So far works nice! :D

  • 1 Votes
    2 Posts
    761 Views
    C

    I eventually managed to fix this by implementing updateEditorGeometry and calling editor->setGeometry(option.rect);. I should have looked into base class member functions sooner!

  • 0 Votes
    20 Posts
    9k Views
    D

    Hey

    Got a follow up question in regards to styling...

    How can I get QComboBox focus indicator/rect ? So that I can set correct color for the outline of comboBox to paint?

    I tried using

    QRect r = QApplication::style()->subElementRect(QStyle::SE_ComboBoxLayoutItem, &option, mWidgetList[ComboBox]);

    and

    QRect r = QApplication::style()->subElementRect(QStyle::SE_ComboBoxFocusRect, &option, mWidgetList[ComboBox]);

    But neither return correct rect to use as paint target... Only the large square one around item in tree view.

    Any hints?

    Same for QPushButton, and pretty much any button/combo like widget I think o.O

    TIA.

  • 0 Votes
    6 Posts
    2k Views
    P

    I updated the QT version to 5.11 and the problem goes away. No need to implement the leaveEvent of the QListView.
    Tested also with 5.10 and it worked there as well.

  • 0 Votes
    5 Posts
    2k Views
    CybeXC

    @SGaist
    Platform - Linux x86_64
    Qt Version - 5.9.3

    @JNBarchan
    fontHeight produced a integer value +/- 56
    iconHeight produced an integer value ( < fontHeight)

    @VRonin
    The Role's where not the problem. Please see my updated delegate below (kudos for calling it, the delegate being the problem)

    Well this is embarrasing. I did not fully realize what I was coding until I had battled with the delegate all night.

    I understood that I was coding a template, and assumed that on each item which was added, the origin remained at [0,0]. This was not the case as there was an offset added of value specified in the sizeHint (in my case, 56). Thus all my QListView's QStandardItem's were in fact there, but drawn over each other.

    After changing values and experimenting over a long period (a number of hours), I finally came to the desired result, shown below.

    Also, I need to thank scopchanov for his hint into this offset problem

    StackoverFlow question as a reference

    Updated ServerDelegate.cpp

    #include "serverdelegate.h" ServerDelegate::ServerDelegate(QStyledItemDelegate *parent) : QStyledItemDelegate(parent) { fontCountry = QApplication::font(); fontCountry.setBold(true); fontCountry.setPointSize(QApplication::font().pointSize() + 3); fontCity = QApplication::font(); fontCity.setItalic(true); fontCity.setPointSize(QApplication::font().pointSize() - 1); } ServerDelegate::~ServerDelegate(){ } QSize ServerDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const{ Q_UNUSED(index) QSize totalCountrySize = Global::getCountryFlagFromCache(index.data(DataRole::CountryText).toString()).size(); QSize totalSideIcon = QPixmap(":/res/images/premium", "PNG").size(); QFontMetrics fmCountry(fontCountry); QFontMetrics fmCity(fontCity); int fontHeight = (2 * AppGlobal::Style_List_Seperator_Width) + (2 * AppGlobal::Style_List_Text_Item_Margin) + fmCountry.height() + fmCity.height(); int iconHeight = (2 * AppGlobal::Style_List_Seperator_Width) + (totalCountrySize.height() > totalSideIcon.height() ? totalCountrySize.height() : totalSideIcon.height()); int height = (fontHeight > iconHeight) ? fontHeight : iconHeight; int width = option.rect.width(); QSize size = QSize(width, height); return size; } void ServerDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{ QStyledItemDelegate::paint(painter, option, index); QFontMetrics fmCountry(fontCountry); QFontMetrics fmCity(fontCity); QRect rec = option.rect; painter->save(); painter->setClipRect(rec); QString countryText = index.data(DataRole::CountryText).toString(); QString cityText = index.data(DataRole::CityText).toString(); QPixmap countryFlag = QPixmap(qvariant_cast<QPixmap>(index.data(DataRole::CountryFlag))); QPixmap sideIcon = qvariant_cast<QPixmap>(index.data(DataRole::SideIconFlag)); // Get a rectangle by size x, y. // With cooridinates [0,0]; [x,0]; [x,y]; [0,y] QRect topLine = option.rect, bottomLine = option.rect; // create top 'seperator' of X px's width, green in color; topLine.setTop(rec.top()); topLine.setLeft(rec.left()); topLine.setRight(rec.right()); topLine.setBottom(rec.top() + AppGlobal::Style_List_Seperator_Width); // 1px down painter->setPen(AppGlobal::Style_List_Seperator_Color); painter->fillRect(topLine, AppGlobal::Style_List_Seperator_Color); painter->drawRect(topLine); // create bottom 'seperator' of X px's width, green in color; bottomLine.setTop(rec.bottom() - AppGlobal::Style_List_Seperator_Width); bottomLine.setLeft(rec.left()); bottomLine.setRight(rec.right()); bottomLine.setBottom(rec.bottom()); // 1px down painter->setPen(AppGlobal::Style_List_Seperator_Color); painter->fillRect(bottomLine, AppGlobal::Style_List_Seperator_Color); painter->drawRect(bottomLine); // create background rectangle QRect content(rec.left(), topLine.bottom(), (rec.right() - rec.left()), (bottomLine.top() - topLine.bottom())); painter->setPen(AppGlobal::Style_List_Background_Color); painter->fillRect(content, ((option.state & QStyle::State_MouseOver) ? AppGlobal::Style_List_Hover_Color : AppGlobal::Style_List_Background_Color )); painter->drawRect(content); // create content rectangles from content container. QRect rectCountryFlag = content, rectSideIcon = content; // create country icon rectangle QSize countryFlagSize = countryFlag.size(); int cFPos = ((rectCountryFlag.bottom() - rectCountryFlag.top()) / 2) - (countryFlagSize.height() / 2) - 8; rectCountryFlag.setTop(rectCountryFlag.top() + cFPos); rectCountryFlag.setBottom(content.bottom() - cFPos); rectCountryFlag.setLeft(AppGlobal::Style_List_Left_Item_Margin - 8); rectCountryFlag.setRight(AppGlobal::Style_List_Left_Item_Margin + 16 + countryFlagSize.width()); painter->drawPixmap(rectCountryFlag, countryFlag); // create side icon rectangle QSize sideIconSize = sideIcon.size(); int siPos = ((rectSideIcon.bottom() - rectSideIcon.top()) / 2) - (sideIconSize.height() / 2) - 4; rectSideIcon.setTop(rectSideIcon.top() + siPos); rectSideIcon.setBottom(content.bottom() - siPos); rectSideIcon.setLeft(rec.width() - (AppGlobal::Style_List_Right_Item_Margin + 8 + sideIconSize.width())); rectSideIcon.setRight(rec.width() - AppGlobal::Style_List_Right_Item_Margin); painter->drawPixmap(rectSideIcon, sideIcon); int textContentLeft = rectCountryFlag.right() + AppGlobal::Style_List_Text_Item_Margin + AppGlobal::Style_List_Left_Item_Margin, textContentTop = content.top() + AppGlobal::Style_List_Text_Item_Margin; const QRect textContent( textContentLeft , textContentTop, (rectSideIcon.left() - AppGlobal::Style_List_Text_Item_Margin) - textContentLeft, (content.bottom() - AppGlobal::Style_List_Text_Item_Margin) - textContentTop); // create country text rectangle QRect rectCountryText = content, rectCityText = content; rectCountryText.setLeft(textContent.left()); rectCountryText.setTop(textContent.top()); rectCountryText.setRight(textContent.right()); rectCountryText.setBottom(textContent.top() + fmCountry.height()); painter->setPen(AppGlobal::Style_Heading_Color); painter->setFont(fontCountry); painter->drawText(rectCountryText, countryText); // create city text rectangle rectCityText.setLeft(textContent.left() + ( 2 * AppGlobal::Style_List_Text_Item_Margin)); rectCityText.setTop(rectCountryText.bottom()); rectCityText.setRight(textContent.right()); rectCityText.setBottom(textContent.bottom() + fmCity.height()); painter->setPen(AppGlobal::Style_SubText_Color); painter->setFont(fontCity); painter->drawText(rectCityText, cityText); // restore painter painter->restore(); }
  • 0 Votes
    4 Posts
    3k Views
    VRoninV

    Actually, since the base class already has a virtual destructor you can just remove the destructor of your derived altogether

  • 0 Votes
    5 Posts
    3k Views
    L

    @SGaist Just a simple lined border. At present, this border applies behind the background and isn't visible. There's also the issue of the existing dotted border that I'd want to remove/replace.

  • 0 Votes
    2 Posts
    4k Views
    michalosM

    Ok. I've found the answer.

    I subclass the QTreeView and override the void resizeEvent(QResizeEvent* e) as shown:

    void MyTreeView::resizeEvent(QResizeEvent *e) { if(model() != Q_NULLPTR){ model()->layoutChanged(); } QTreeView::resizeEvent(e); }

    And it did the trick.

    Had help from the Voidrealms Facebook group.

  • 0 Votes
    2 Posts
    2k Views
    raven-worxR

    @alizadeh91
    Either you paint it yourself since you already have the QModelIndex at hand:

    QColor color = index.data( Qt::BackgroundColorRole ).toColor();

    or by letting the style paint the stuff. Note that this also paints the selected background.

    style->drawPrimitive( QStyle::PE_PanelItemViewItem, &option, painter, widget );
  • 0 Votes
    3 Posts
    3k Views
    cfdevC

    @skebanga Many thx!