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
    Thanks
    20
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: A few queries about Model View Programming

    Quote Originally Posted by wysota View Post
    A simple rule says - never return a pointer from data(). Another simple rule says - take a working application that does what you want and look how it does it. A third rule says - Qt examples and demos are nice working applications
    ya, actually i have read the Qt MVC tutorial from Qt Docs. I also looked at some examples.
    Can you please answer my query regarding displaying an icon along with the text in the same field of the QTableView item?

    One more query:
    The data i want to display is coming as follows from the database:

    struct myData {
    QStringList trackName;
    QStringList artistName;
    QStringList time;
    }

    trackName string list contains all rows of the tracks fetched from the database, similarly artistName and time contains all rows of artist names and times corresponding to track names.

    Now, which subclassing which model class should be suitable for me considering that i'll be displaying the data in a QTableView?

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

    Default Re: A few queries about Model View Programming

    Ok i studied the AddressBook example in Qt Item Views examples directory. I think i can subclass QAbstractTableModel to create my own model by rewriting the necessary functions.

    struct myData {
    QStringList trackName;
    QStringList artistName;
    QStringList time;
    }

    trackName string list contains all rows of the tracks fetched from the database, similarly artistName and time contains all rows of artist names and times corresponding to track names.
    Now, since i am getting the data from the database column vise, i would need to get individual items from the QStringList and put that in another list. This way i have to create a new list for each row, so that i can add it to a row in QTableView.

    In the Address Book example, a list of QPair is used to maintain data for each row (since it has only 2 columns):
    QList< QPair<QString, QString> > listOfPairs;

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

    QList<QStringList> myList;

    So, each entry in myList would correspond to one row in the model or QTableView. Then i can just add the data in QTableView as done in the Address Book example.

    Please comment if the above approach will work or not.

    One problem:
    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.

  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: 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...

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

    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.

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    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.

  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: 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.

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    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 

  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: 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...

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    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?

  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: 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

  11. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    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.

  12. #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: 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?

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.