Results 1 to 16 of 16

Thread: QTableView: sizeHint() not getting invoked for custom delegate

  1. #1
    Join Date
    Oct 2007
    Location
    India
    Posts
    162
    Thanks
    20
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Question QTableView: sizeHint() not getting invoked for custom delegate

    I have a QTableView and i am using a custom delegate to display the content in the table view. I have subclassed the QStyledItemDelegate class and reimplemented the paint() function. Now, i want to increase the height of the table view row so that only 8 rows are visible at a time. I tried reimplementing the sizeHint() function of QStyledItemDelegate class but it's not getting invoked at all. I even added exit(1) inside the function to check if it is being invoked.

    I don't get why it's not being called. I reimplemented the paint function and it's called automatically so what's the problem with sizeHint()?

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    How does the reimplementation look like?

  3. #3
    Join Date
    Oct 2007
    Location
    India
    Posts
    162
    Thanks
    20
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    reimplementation of sizeHint() is empty for now. I am just having a qDebug() statement and exit(1) in sizeHint() to check if the function is actually getting called. But nothing is displayed and my program doesn't exit.

    I am setting some options for the table view like allowing single selection, hiding headers etc. Can this be the reason that sizeHint() is not being called? It seems idiotic to me but this thought came to my mind.

    Here's how i am reimplementing sizeHint():

    Header file:
    Qt Code:
    1. class CustomDelegate : public QAbstractItemDelegate
    2. {
    3. public:
    4. CustomDelegate(QObject *parent=0);
    5. // Public member functions
    6. void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    7. QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
    8. };
    To copy to clipboard, switch view to plain text mode 

    C++ file:
    Qt Code:
    1. void CustomDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    2. {
    3. // Paint implementation
    4. }
    5.  
    6. QSize CustomDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    7. {
    8. qDebug("Inside sizeHint");
    9. exit(1);
    10. }
    To copy to clipboard, switch view to plain text mode 

    Now, when i run my application, paint() is called but sizeHint() is not getting called. I don't why sizeHint() is not being called

  4. #4
    Join Date
    Oct 2006
    Location
    New Delhi, India
    Posts
    2,467
    Thanks
    8
    Thanked 334 Times in 317 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    2 questions -
    Have you added any data to the tableview ?
    If you are using your model, try playing with sizeHintRole.

    second, what if you inherit from QItemDelegate instead of QAbstractItemDelegate ?

  5. #5
    Join Date
    Oct 2007
    Location
    India
    Posts
    162
    Thanks
    20
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    Quote Originally Posted by aamer4yu View Post
    2 questions -
    Have you added any data to the tableview ?
    If you are using your model, try playing with sizeHintRole.

    second, what if you inherit from QItemDelegate instead of QAbstractItemDelegate ?
    yup, i have added data in the model and it's displayed properly in the table view.
    I even added code for sizeHintRole in the data() function of the model, still it doesn't execute the code inside sizeHintRole.
    Don't know what's wrong. sizeHint() is supposed to be called automatically i guess.

    I tried inhering from QAbstractItemDelegate, QStyledItemDelegate and QItemDelegate but none of these seem to work for sizeHint.

    I'll try to reproduce the problem in a separate application and try to post it here.

    BTW, here's the flags() function code from my model. Don't know if this has anything to do with my problem.

    Qt Code:
    1. Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
    2. {
    3. if (!index.isValid())
    4. return Qt::ItemIsEnabled;
    5.  
    6. if (index.column() == CHECKBOX_COLUMN)
    7. { // Make the checkbox column items checkable
    8. return QAbstractTableModel::flags(index) | Qt::ItemIsUserCheckable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
    9. }
    10. else
    11. {
    12. return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
    13. }
    14. }
    To copy to clipboard, switch view to plain text mode 
    Is there any other way to set the height of rows in the table view? Basically my requirement is to increase the row height so that only 8 rows are visible in the table at a time without scrolling.
    Last edited by montylee; 18th February 2009 at 18:30.

  6. #6
    Join Date
    Oct 2007
    Location
    India
    Posts
    162
    Thanks
    20
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    Here's a sample code which reproduces the problem:

    Qt Code:
    1. #include <QApplication>
    2. #include <QListView>
    3. #include <QTableView>
    4. #include <QAbstractItemDelegate>
    5. #include <QStandardItemModel>
    6. #include <QPainter>
    7. class PluginDelegate : public QAbstractItemDelegate {
    8. public:
    9. PluginDelegate(QObject *parent=0) : QAbstractItemDelegate(parent){}
    10. void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const{
    11. if(option.state & QStyle::State_Selected){
    12. painter->fillRect(option.rect, option.palette.color(QPalette::Highlight));
    13. }
    14. QIcon ic = QIcon(qvariant_cast<QPixmap>(index.data(Qt::DecorationRole)));
    15. QString txt = index.data(Qt::DisplayRole).toString();
    16. QRect r = option.rect.adjusted(2, 2, -2, -2);
    17. ic.paint(painter, r, Qt::AlignVCenter|Qt::AlignLeft);
    18. r = r.adjusted(r.height()+20, 0, 0, 0);
    19. painter->drawText(r.left(), r.top(), r.width(), r.height(), Qt::AlignVCenter|Qt::AlignLeft|Qt::TextWordWrap, txt, &r);
    20. }
    21. QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const{
    22. qDebug("in sizeHint()");
    23. exit(1);
    24. //return QSize(200, 82); // very dumb value
    25. }
    26.  
    27. };
    28.  
    29. int main(int argc, char **argv){
    30. QApplication app(argc, argv);
    31. //QListView lv;
    32. model.setRowCount(2);
    33. model.setColumnCount(1);
    34. model.setData(model.index(0, 0), QPixmap("/usr/share/icons/crystalsvg/32x32/actions/filenew.png"), Qt::DecorationRole);
    35. model.setData(model.index(0, 0), "Some wonderful text which is long enough to cover more than one row");
    36. model.setData(model.index(1, 0), QPixmap("/usr/share/icons/crystalsvg/32x32/actions/exit.png"), Qt::DecorationRole);
    37. model.setData(model.index(1, 0), "Some wonderful text");
    38. lv.setModel(&model);
    39. lv.setItemDelegate(new PluginDelegate(&lv));
    40. lv.setAlternatingRowColors(true);
    41. lv.show();
    42. return app.exec();
    43. }
    To copy to clipboard, switch view to plain text mode 

    If i use table view in the above code, sizeHint() is not called at all. But if i replace table view with a list view, sizeHint() is called and the row height is set properly.

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    What happens if you hide the headers?

  8. #8
    Join Date
    Oct 2007
    Location
    India
    Posts
    162
    Thanks
    20
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    Quote Originally Posted by wysota View Post
    What happens if you hide the headers?
    sorry, i didn't get what you mean.
    The headers of my table are hidden and hiding/displaying the headers have no difference in the sample application i posted.

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate


  10. #10
    Join Date
    Oct 2007
    Location
    India
    Posts
    162
    Thanks
    20
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    i can try using QTableView::resizeRowsToContents() but i am not sure it will work for me properly. I am drawing the text being displayed in the table rows myself in the paint() function. So, to display only 8 rows in the table at a time, i increase the font size but from where will QTableView::resizeRowsToContents() get the sizeHint? I guess it will use the default size hint. But i want to specify the size hint myself so that i can control the row height myself.
    I'll try using QTableView::resizeRowsToContents() tomorrow when i work on the code.

    And the most important question is that why isn't sizeHint() getting called for QTableView? Is it a known issue? I don't think it is mentioned anywhere in the Qt Documentation that sizeHint() doesn't work for QTableView, so i guess it's a bug. Even if it doesn't work, there should be atleast some way to specify the row height in QTableView.

    Can you try to run the sample application code i posted and observe the difference in behavior of sizeHint() for QTableView and QListView?

  11. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    Quote Originally Posted by montylee View Post
    I guess it will use the default size hint.
    It will ask the delegate for the size hint.

    And the most important question is that why isn't sizeHint() getting called for QTableView?
    Because in the default mode the headers control cell sizes, not the other way round. If you change the resize mode of the headers to ResizeToContents it will ask the contents for the size.

    Is it a known issue?
    Yes, it's called a feature

  12. The following user says thank you to wysota for this useful post:

    montylee (19th February 2009)

  13. #12
    Join Date
    Oct 2007
    Location
    India
    Posts
    162
    Thanks
    20
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    aah, you are right! After calling QTableView::resizeRowsToContents() sizeHint() is being called and looks like my problem is resolved

    I'll test this code in my main application tomorrow.

    Thanks!!! looks like once again you rescued me

  14. #13
    Join Date
    Oct 2007
    Location
    India
    Posts
    162
    Thanks
    20
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    ok, i am able to set the row height properly now in my main application.
    So, this was not a bug i guess. But it should be mentioned in the documentation of sizeHint() that one needs to use set QTableView::resizeRowsToContents() and QTableView::resizeColumnsToContents() to use sizeHint.

  15. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    Why should the docs of the delegate contain information about a special behaviour of some other widget? The information you are looking for is there, just not in the place you were looking for it.

    See QHeaderView::ResizeMode, especially the last (not counting the one in brackets) sentence from the Interactive value description and first sentence of ResizeToContents value description.

  16. #15
    Join Date
    Jan 2008
    Location
    Germany
    Posts
    80
    Thanks
    6
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    Where is resizeRowsToContents() supposed to be called when the model gets updated?

  17. #16
    Join Date
    Dec 2012
    Posts
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Windows

    Default Re: QTableView: sizeHint() not getting invoked for custom delegate

    I know this is resurrecting an old thread, but I wound-up here when trying to figure out why sizeHint wasn't being called when overridden in a custom QGraphicsWidget.
    Someone might wind-up here, so I'll add my discovery that having called setContentsMargins at any time before layout will solve this problem.

Similar Threads

  1. QTableView sizeHint() issues
    By akos.maroy in forum Qt Programming
    Replies: 3
    Last Post: 20th September 2008, 22:42

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.