Results 1 to 20 of 47

Thread: A few queries about Model View Programming

Hybrid View

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

    Default Re: A few queries about Model View Programming

    I managed to display the data along with the checkbox in the QTableView properly using the QList<QStringList> approach i mentioned.

    Now, the only problem is that i am not able to edit (check/uncheck) the checkbox. The setData function looks like this:

    bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
    if (index.isValid() && role == Qt::EditRole) {
    // Do something
    } else {
    if (index.isValid() && role == Qt::CheckStateRole) {
    emit(dataChanged(index, index));
    return true;
    }
    }
    I am not sure what to write in the else condition for Qt::CheckStateRole.

    The data() function has the following code:

    if (role == Qt::CheckStateRole) {
    if (index.column() == 3)
    return (index.model()->data(index).toInt() != 0) ? Qt::Checked : Qt::Unchecked;
    I think data() function is fine as i am able to view the checkbox.

    Please help...

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

    Talking Re: A few queries about Model View Programming

    somebody please help! I just need to make the checkboxes editable now.

    Edit: Nevermind, i got it working. Here's how i did it:

    Defined a private variable in the model header file to store status of all checkboxes:

    QList<bool> m_checkedStates;
    data() function:
    if (role == Qt::CheckStateRole && index.column() == 3) {
    if (m_checkedStates[index.row()] == true)
    return Qt::Checked;
    else
    return Qt::Unchecked;
    setData() function:
    if (role == Qt::CheckStateRole && index.column() == 3) {
    m_checkedStates[index.row()] = !m_checkedStates[index.row()];
    emit dataChanged(index, index);
    return true;
    }
    Thanks a lot everyone for helping me out!

    One final query:
    If i want to draw the checkbox my self using QPainter, how to do it in this code?
    Last edited by montylee; 17th December 2008 at 18:25.

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

    Default Re: A few queries about Model View Programming

    Quote Originally Posted by muellerp View Post
    Just a side question to "A simple rule says - never return a pointer from data(). ".

    How would I return a QList?
    You can return a QVariantList which is a QList of QVariant.
    AFAIK the data() returns a copy of the QList. This would be in my case very sad.
    Why so?

    Or is the copy not a deep copy as it is implicitely shared, so using data with QList (or similar bigger objects) is not that harmful to speed and memory consumption?
    The copy is always shallow as long as you don't modify it.

    Quote Originally Posted by montylee View Post
    Can you please answer my query regarding displaying an icon along with the text in the same field of the QTableView item?
    Haven't you seen any example that does that? In general you must be able to return data for both roles - QString for DisplayRole and QIcon or QPixmap for DecorationRole.

    Now, which subclassing which model class should be suitable for me considering that i'll be displaying the data in a QTableView?
    If you don't know which model to use, QStandardItemModel is almost always a good choice. If you are using a database though, you might want to use QSqlQueryModel or one of its descendants.


    but since i have more than 2 columns, i am thinking of using a QList of QStringList i.e.

    QList<QStringList> myList;
    Bad choice.

    QList<MyStruct> is much better.


    I was able to get a checkbox in the 3rd column by modifying the data() and flags() functions of the Address Book example. But i can only view the checkbox, i am not able to edit it. I am not sure what code to write in setData() function, so please help me.
    setData() must be able to set the CheckStateRole on the index and flags() must return ItemIsUserCheckable.

    If i want to draw the checkbox my self using QPainter, how to do it in this code?
    By setting a custom delegate and using QStyle::drawPrimitive() and PE_IndicatorCheckBox.

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

    Default Re: A few queries about Model View Programming

    Quote Originally Posted by wysota View Post
    Haven't you seen any example that does that? In general you must be able to return data for both roles - QString for DisplayRole and QIcon or QPixmap for DecorationRole.
    I'll try searching the Qt example for the icon thing. I managed to get the icon along with the song name. Here's the code:

    if (role == Qt:ecorationRole && index.column() == 0) {
    QPixmap pixmap ("icon.png");
    return pixmap;
    }
    So, in the end it was pretty simple to get the icon.

    Quote Originally Posted by wysota View Post
    If you don't know which model to use, QStandardItemModel is almost always a good choice. If you are using a database though, you might want to use QSqlQueryModel or one of its descendants.
    I have decided to use QAbstractTableModel as it fits my requirements perfectly.

    Quote Originally Posted by wysota View Post
    Bad choice.

    QList<MyStruct> is much better.
    Actually the data from the database is already coming as a QStringList so i have to use a QList of QStringList, so i have no choice here.

    Quote Originally Posted by wysota View Post
    By setting a custom delegate and using QStyle::drawPrimitive() and PE_IndicatorCheckBox.
    But using custom delegate i think the custom drawing will only be visible to the user when it goes into edit mode. I want the custom drawing to be visible at all times. Currently the normal checkbox (using QCheckBoxRole) is visible at all times, so i just want to add custom drawing to it. But i am not sure how to draw it as it's not a real checkbox, so a normal custom delegate might not work.
    Last edited by montylee; 17th December 2008 at 22:48.

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

    Default Re: A few queries about Model View Programming

    Quote Originally Posted by montylee View Post
    But using custom delegate i think the custom drawing will only be visible to the user when it goes into edit mode.
    No, that's incorrect. Everything you see in the table is drawn by the delegate. Take a look at QTableView source code, there is no code related to rendering items.

    Currently the normal checkbox is visible at all times, so i just want to add custom drawing to it. But i am not sure how to draw it as it's not a real checkbox.
    It's not a real checkbox. It's drawn by the delegate. Here is the code it uses:

    Qt Code:
    1. void QItemDelegate::drawCheck(QPainter *painter,
    2. const QStyleOptionViewItem &option,
    3. const QRect &rect, Qt::CheckState state) const
    4. {
    5. Q_D(const QItemDelegate);
    6. if (!rect.isValid())
    7. return;
    8.  
    9. QStyleOptionViewItem opt(option);
    10. opt.rect = rect;
    11. opt.state = opt.state & ~QStyle::State_HasFocus;
    12.  
    13. switch (state) {
    14. case Qt::Unchecked:
    15. opt.state |= QStyle::State_Off;
    16. break;
    17. case Qt::PartiallyChecked:
    18. opt.state |= QStyle::State_NoChange;
    19. break;
    20. case Qt::Checked:
    21. opt.state |= QStyle::State_On;
    22. break;
    23. }
    24.  
    25. const QWidget *widget = d->widget(option);
    26. QStyle *style = widget ? widget->style() : QApplication::style();
    27. style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt, painter, widget);
    28. }
    To copy to clipboard, switch view to plain text mode 

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

    Default Re: A few queries about Model View Programming

    Ok ,so it seems that it is possible to draw a custom checkbox which is visible at all times using a custom delegate.
    But i am still confused as to how to implement a custom painted checkbox which will be visible at all times. My current code has the normal checkbox working using Qt::CheckStateRole as you suggested earlier. Now, if i want to add custom drawing to it, what should i do?

    Suppose, i write a custom delegate to display a checkbox at all times. So, i'll rewrite the paint function of the delegate to display a virtual checkbox at all times. In addition, to support editing of the checkbox (check/uncheck) by the user, i need to rewrite the createEditor(), setEditorData() and setModelData() functions in the custom delegate.

    So, when the application runs, user will see a virtual checkbox because of the paint() function of the custom delegate and if the user clicks the checkbox, the delegate should go into edit mode and have a real checkbox.

    Is the above understanding correct? If i implement the above stuff, i would have to remove the Qt::CheckStateRole code as it will no longer be used.

    I am still confused...

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

    Default Re: A few queries about Model View Programming

    Quote Originally Posted by montylee View Post
    Ok ,so it seems that it is possible to draw a custom checkbox which is visible at all times using a custom delegate.
    Honestly I don't see a point of doing that if the default delegate already does it.

    But i am still confused as to how to implement a custom painted checkbox which will be visible at all times.
    The code is in my previous post. It's taken directly from Qt sources.

    My current code has the normal checkbox working using Qt::CheckStateRole as you suggested earlier. Now, if i want to add custom drawing to it, what should i do?
    It's not a "normal" checkbox. It uses the code from my previous post.

    Suppose, i write a custom delegate to display a checkbox at all times. So, i'll rewrite the paint function of the delegate to display a virtual checkbox at all times. In addition, to support editing of the checkbox (check/uncheck) by the user, i need to rewrite the createEditor(), setEditorData() and setModelData() functions in the custom delegate.
    Could you first say what is the effect you want to achieve that is not available by default?

    So, when the application runs, user will see a virtual checkbox because of the paint() function of the custom delegate and if the user clicks the checkbox, the delegate should go into edit mode and have a real checkbox.
    Why would you want a real checkbox? What's wrong with the one the CheckStateRole provides?

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

    Default Re: A few queries about Model View Programming

    Quote Originally Posted by wysota View Post
    Honestly I don't see a point of doing that if the default delegate already does it.

    The code is in my previous post. It's taken directly from Qt sources.

    It's not a "normal" checkbox. It uses the code from my previous post.
    So you are saying that Qt::CheckStateRole actually uses the code which you pasted. So, basically it is just custom painting the checkbox.

    Now, since i am already using Qt::CheckStateRole to get the checkbox, i need to add custom painting to it.

    Quote Originally Posted by wysota View Post
    Could you first say what is the effect you want to achieve that is not available by default?


    Why would you want a real checkbox? What's wrong with the one the CheckStateRole provides?
    As i already mentioned. I just want a checkbox which is visible at all times and user can edit it. I have already implemented this functionality using Qt::CheckStateRole as you can see from the attached image. So, i am happy with what Qt::CheckStateRole has provided. Now, i just want to add custom painting to the visible checkboxes.
    Attached Images Attached Images

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

    Default Re: A few queries about Model View Programming

    You can do that either by using style sheets or by subclassing one of the available delegate classes and reimplementing the way the checkbox is drawn.

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

    Default Re: A few queries about Model View Programming

    Quote Originally Posted by wysota View Post
    You can do that either by using style sheets or by subclassing one of the available delegate classes and reimplementing the way the checkbox is drawn.
    if i use a delegate class for drawing the checkbox, can i continue using Qt::CheckStateRole for displaying the checkbox and handle only drawing in the custom delegate?

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

    Default Re: A few queries about Model View Programming

    You already are using a delegate to draw the checkbox. You just need to subclass it and draw something different instead of what the default delegate draws, for example by reimplementing QItemDelegate::drawCheck().

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

    montylee (18th December 2008)

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

    Default Re: A few queries about Model View Programming

    Quote Originally Posted by wysota View Post
    You already are using a delegate to draw the checkbox. You just need to subclass it and draw something different instead of what the default delegate draws, for example by reimplementing QItemDelegate::drawCheck().
    Hmmm...that looks cool. Thanks a lot for helping me out in MVC. I am now beginning to get a hang of it.

    Thanks again!!!

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

    Default Re: A few queries about Model View Programming

    Quote Originally Posted by wysota View Post
    You already are using a delegate to draw the checkbox. You just need to subclass it and draw something different instead of what the default delegate draws, for example by reimplementing QItemDelegate::drawCheck().
    ah, i am still working on the checkbox thing. I am able to display a custom checkbox image by subclassing QItemDelegate::drawCheck(). The drawCheck code is as under:

    Qt Code:
    1. void CheckboxDelegate::drawCheck(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, Qt::CheckState state) const
    2. {
    3. QBrush brush(QColor(19, 19, 70));
    4. QRect r = rect.adjusted(0, -5, 50, 5);
    5. painter->fillRect(r, brush);
    6. r = rect.adjusted(20, -5, 25, 0);
    7. if (state == Qt::Checked)
    8. painter->drawPixmap(r, QPixmap("check-icon.png"));
    9. /*else
    10. painter->drawPixmap(r, QPixmap());*/
    11. }
    To copy to clipboard, switch view to plain text mode 

    So, when i select the checkbox, my custom image is displayed. Now, i have some problems:

    1) When the QTableView row is highlighted, the row highlight color is drawn over my checkbox and the checkbox doesn't show up on the selected row.
    2) How can i give a different checkbox image for the case when a row is highligted? Basically i want to show 2 different checkbox images for highlighted and un-highlighted rows. But since drawCheck() doesn't have QModelIndex as argument, i am not able to find the model index for which drawCheck() is being called. If i can find the model index, i can compare it with the current highlighted row and show a different image for that row.
    3) If i don't use this custom delegate, i get a checkbox in the 3rd column properly but the checkbox is displayed to the extreme left (see attached normal_checkbox.png). If i use my custom checkbox (see attached custom_checkbox.png), i see the checkbox properly but if i click on it, it doesn't toggle the checbox. Actual toggle is done when i click on the extreme left on the cell, so inspite of drawing a custom checkbox, the actual checkbox is to the left. Ideally, the toggle should be done, if user clicks anywhere in the cell.

    In addition, as you can see from custom_checkbox.png, when a row is selected, the checkbox is not shown. Instead a blue area depicting the actual checkbox is shown.
    Attached Images Attached Images

  15. #14
    Join Date
    Oct 2008
    Location
    Europe
    Posts
    37
    Qt products
    Qt4
    Platforms
    Windows
    Thanks
    3
    Thanked 1 Time in 1 Post

    Unhappy Re: A few queries about Model View Programming

    Thanks for great advice on this great thread !!!!

    Problem: can anyone tell me how to move the checkbox to the RIGHT ??

    I think it has something to do with const QStyleOptionViewItem &option;
    but i simply cant do: option.decorationPosition=QStyleOptionViewItem::Ri ght;
    I am subclassing QStyledItemDelegate if it matters...
    Attached Images Attached Images

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

    Default Re: A few queries about Model View Programming

    Check box is not a decoration so you can't do it this way. You have to provide your own delegate that handles painting and clicking the box in the new position. There is a chance you can move the checkbox to the right if you manage to convince the item it should be there in the first place (for example by reimplementing a proper function from the QStyle subclass you use).

Similar Threads

  1. hierarchical model in a flat view
    By gniking in forum Qt Programming
    Replies: 4
    Last Post: 10th November 2009, 20:17
  2. model View programming problem
    By mismael85 in forum Qt Programming
    Replies: 3
    Last Post: 2nd April 2008, 21:44
  3. Model, View and Proxy
    By No-Nonsense in forum Qt Programming
    Replies: 2
    Last Post: 21st November 2006, 08:50
  4. Model - View Programming doubt.
    By munna in forum Qt Programming
    Replies: 4
    Last Post: 28th April 2006, 13:01
  5. Replies: 6
    Last Post: 20th April 2006, 10:23

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
  •  
Qt is a trademark of The Qt Company.