Skip to content
  • 0 Votes
    5 Posts
    3k 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
    2 Posts
    2k Views
    raven-worxR

    @Yohdu said:

    My second and main question is then : how to implement correct drag and drop operations with custom QStandardItem which needs to own custom data ?

    With the standard item widgets/models you can't drag-n-drop custom item roles.
    This makes sense, since the model doesn't know which UserRole+ was set.
    It would need to iterate all possible item-role values when creating the drop-data.

    The only solution i see is to create your own custom model and reimplement the needed drag-n-drop methods. This also give you full control over your data structure storing the data inside the model.
    This is more work, but you will learn a lot and gain some performance (by avoiding the standard-item classes)

  • 0 Votes
    2 Posts
    983 Views
    ValentinMicheletV

    Hi, welcome to Devnet.

    The things you have to understand with hierarchical model are:

    everything can be done through items use appendRows (or insertRows) to add one line containing several columns create a hierarchy on the item that represents the first column with the above appendRows (for instance on "(fffe,e000)" but not on "SQ") use appendRows (or insertRows) on top level instances only to your model (for instance "(0040,a493)" "CS", "(0040,a504)" "SQ", but not "(0008,0105)" "CS")

    To view your hierarchy, create a QTreeView and give it this model.

    If it's not clear enough, just let me know.

  • 0 Votes
    4 Posts
    1k Views
    Chris KawaC

    You're setting the wrong role. See my answer here.

  • 0 Votes
    3 Posts
    1k Views
    A

    @SGaist Hi, nothing, it compiles ok and runs.
    The only closest thing is a flaw in my fix, though just a warning
    And when it crashes, nothing as far as I can tell or find.

  • 0 Votes
    1 Posts
    791 Views
    No one has replied
  • 0 Votes
    8 Posts
    4k Views
    P

    Oh well. I didn't have a reason for doing that, it was just plain ignorance.
    I corrected that, and also one more thing. I eliminate the std::string from

    std::string strtmp(attr->value()); oCol.item(i-1)->setText(QString::fromStdString(strtmp));

    Standard c++ strings might not cope well with UTF-8 encoding. So I changed it to

    QString strtmp(attr->value()); oCol.item(i-1)->setText(strtmp);

    These two changes combined have solved it. Thank you very much!

  • 0 Votes
    5 Posts
    4k Views
    I

    use this
    QComboBox QAbstractItemView {
    selection-background-color: lightgray;
    }

    QAbstractItemView::indicator {
    background-color: rgb(0, 255, 0);
    width :20;
    height :20;
    }
    QAbstractItemView::indicator:checked {
    background-color: rgb(255, 170, 0);
    }

  • 0 Votes
    5 Posts
    2k Views
    A

    Hmm OK,

    Think I get it.
    What you say is I have to create my own class inherrited from QAbstractItemModel
    And in the class implementation modify to my usage

    OK, I'll give it a try and see where it leads me.

    Thanks for the reply, hope its the answer to my problem.
    Close the thread for now... somehow

  • 0 Votes
    4 Posts
    2k Views
    M

    @MaestroMaus Nevermind; found it. Qt has a custom way of downcasting QVariant subclasses. I can just ask the type via a standard method.

  • 0 Votes
    3 Posts
    2k Views
    sahadumS

    Hi,

    thx, I added a report to Qt Jira.

    QTBUG-45114