Page 1 of 3 123 LastLast
Results 1 to 20 of 47

Thread: A few queries about Model View Programming

  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 A few queries about Model View Programming

    I have a database consisting of a table with some fields. I am using QSqlTableModel to get the data from the database and displaying it in a QTableView. Now, the database has 3 fields i.e. tracks, artist and time. All of the data in these fields is coming from the model and being displayed properly.
    I have added another column to the QTableView consisting of QCheckBox for each row (See attached image). The QCheckBox is not part of the database or model. I am using the following code for attaching QCheckBox to each row:

    Qt Code:
    1. void MyClass::createCheckItems(QTableView *table)
    2. {
    3. for (int i = 0; i < m_pModel->rowCount(); ++i) {
    4. QCheckBox *cbox = new QCheckBox(QObject::tr (""));
    5. // Enable autofill of the widget background to hide the model data
    6. cbox->setAutoFillBackground(TRUE);
    7. // Set up slots
    8. connect(cbox, SIGNAL(stateChanged(int)), this, SLOT(checkBoxClicked(int)));
    9. // Add checkboxes in the 4th column of QTableView
    10. table->setIndexWidget(m_pModel->index(i, 3), cbox);
    11. }
    12. }
    To copy to clipboard, switch view to plain text mode 

    I am able to retrieve the current row and get the track name when the user clicks on a check box.

    My queries:
    1) I am using setIndexWidget() to display checkboxes in the 4th column and my code is working fine. Is it ok or should i use QItemDelegate to add checboxes?
    2) Currently the QTableView displays data directly received from the model (database). But suppose, i want to format the data received from the model before displaying on the QTableView, how can i do it? For e.g. suppose the "time" field is stored as seconds in the database and i want to display it in "minutes:seconds" in the QTableView, how can i do that?
    3) I want to do custom drawing in the "tracks" field, for e.g. the currently playing track might have an icon next to the track name. How to do that?

    Thanks in advance!
    Attached Images Attached Images
    • File Type: png 1.png (24.1 KB, 241 views)

  2. #2
    Join Date
    Aug 2008
    Location
    Nanjing, China
    Posts
    66
    Thanks
    12
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: A few queries about Model View Programming

    1) I am using setIndexWidget() to display checkboxes in the 4th column and my code is working fine. Is it ok or should i use QItemDelegate to add checboxes?
    According to my experience with the model/view,If you use delegate, you would change the model either.

    2) Currently the QTableView displays data directly received from the model (database). But suppose, i want to format the data received from the model before displaying on the QTableView, how can i do it? For e.g. suppose the "time" field is stored as seconds in the database and i want to display it in "minutes:seconds" in the QTableView, how can i do that?
    you can write the data() function in the model like this
    Qt Code:
    1. if (role == Qt::DisplayRole)
    2. {
    3. if(index.column() == column_time)
    4. {
    5. //seconds is the "time" field stored value
    6. int min = seconds/60;
    7. int sec = seconds%60;
    8. return QString(%1:%2).arg(min).arg(sec);
    9. }
    10. //.......
    11. }
    To copy to clipboard, switch view to plain text mode 

    3) I want to do custom drawing in the "tracks" field, for e.g. the currently playing track might have an icon next to the track name. How to do that?
    also in the data() func
    Make a QIcon,return it when role == Qt:: DecorationRole
    Last edited by calmspeaker; 12th December 2008 at 03:34.
    Jerry

  3. The following user says thank you to calmspeaker for this useful post:

    montylee (15th December 2008)

  4. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 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
    1) I am using setIndexWidget() to display checkboxes in the 4th column and my code is working fine. Is it ok or should i use QItemDelegate to add checboxes?
    Avoid using index widgets. Use a Qt::CheckStateRole of the model instead - either directly in your model or through a proxy model if you can't modify the base model.

    2) Currently the QTableView displays data directly received from the model (database). But suppose, i want to format the data received from the model before displaying on the QTableView, how can i do it? For e.g. suppose the "time" field is stored as seconds in the database and i want to display it in "minutes:seconds" in the QTableView, how can i do that?
    Provide a custom delegate or use a proxy model that will return different data. If you can change the base model, you might want to either use the solution already posted or introduce a custom role that would return data formatted the way you like it and use a custom delegate to fetch it from the model.

    3) I want to do custom drawing in the "tracks" field, for e.g. the currently playing track might have an icon next to the track name. How to do that?
    Either return the decoration as the Qt::DecorationRole of the model or use a proxy model or a custom delegate.

  5. #4
    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 calmspeaker View Post
    According to my experience with the model/view,If you use delegate, you would change the model either.
    Sorry, i didn't get what you exactly mean.

    Quote Originally Posted by calmspeaker View Post
    you can write the data() function in the model like this
    Qt Code:
    1. if (role == Qt::DisplayRole)
    2. {
    3. if(index.column() == column_time)
    4. {
    5. //seconds is the "time" field stored value
    6. int min = seconds/60;
    7. int sec = seconds%60;
    8. return QString(%1:%2).arg(min).arg(sec);
    9. }
    10. //.......
    11. }
    To copy to clipboard, switch view to plain text mode 
    I haven't used Roles till now and i am new to the MVC architecture. So, can you please tell me how exactly i can use the above function? As far as i understand, i have to subclass the default QSqlTableModel and rewrite the data() function as you have given above. Is it correct? Will the model automatically pick up the formatted data when i use model->setTable(tableName)? Since i am not using data() function directly to fetch the data from the model when the application starts up, the data is automatically filled up as soon as i set the QTableView to use the model. So, just wanted to know if rewriting the data() function will force the model to display formatted data by default.

    Quote Originally Posted by calmspeaker View Post
    also in the data() func
    Make a QIcon,return it when role == Qt:: DecorationRole
    I got what you mean but i am not able to understand how to use it. Suppose i want to display an icon with the song name field. The currently playing track should have an icon next to the track name in addition to the track name. So, is the following code correct:
    Qt Code:
    1. if(index.column() == column_track)
    2. {
    3. if (role == Qt::DecorationRole)
    4. {
    5. QIcon *icon = new QIcon(this);
    6. // Attach image to icon
    7. return QIcon;
    8. }
    9. if (role == Qt::DisplayRole)
    10. {
    11. return index.data();
    12. }
    13. //.......
    14. }
    To copy to clipboard, switch view to plain text mode 
    So, in the above code, i am returning an icon for the tracks column for DecorationRole and returning the track name for DisplayRole. Will index.data() return the track name or do i need to use some other API?
    Will the above code display both the track name and icon when the application starts up?

    One more doubt (same doubt as above): The above code will work if i call the data() explicitly but will the proper data be displayed when the application first starts up?

    Quote Originally Posted by wysota View Post
    Avoid using index widgets. Use a Qt::CheckStateRole of the model instead - either directly in your model or through a proxy model if you can't modify the base model.
    I was thinking about using the CheckStateRole. Please elaborate on the usage of the same. As i mentioned the column containing checkbox is not in the database. I get only the 1st 3 columns from the database and then add checkboxes to the 4th column, The checkboxes are meant for adding songs to a playlist and have nothing to do with the song database.
    So, if i use the following code in the data() function of the model, will it work?
    Qt Code:
    1. if(index.column() == 3) // 4th column for checkboxes
    2. {
    3. if (role == Qt::DisplayRole)
    4. {
    5. QCheckBox *cbox;
    6. return cbox;
    7. }
    8. }
    9. //.......
    10. }
    To copy to clipboard, switch view to plain text mode 
    Is the above code correct? i am not sure about it. In QTableWidget, we can just set the checkstate property to get a checkbox but in QTableView, i am not sure if i have to create a QCheckBox or not.
    And how will i get the events for the checkbox? Basically i want to get the row number or track name when user clicks on a checkbox. So, whenever user selects/deselects a checkbox, i need to get the track name and add/delete it from the playlist.

    Also, since from the database i'll get only 3 columns, how will i add another column to the model without disturbing the database? I am using model->insertColumn() in the code which i posted in my first post.

    Quote Originally Posted by wysota View Post
    Provide a custom delegate or use a proxy model that will return different data. If you can change the base model, you might want to either use the solution already posted or introduce a custom role that would return data formatted the way you like it and use a custom delegate to fetch it from the model.
    I am not familiar with delegates, so the solution posted by @calmspeaker looks ok to me. I don't need to modify the database from the GUI, so i can avoid using the delegates.

    Quote Originally Posted by wysota View Post
    Either return the decoration as the Qt:ecorationRole of the model or use a proxy model or a custom delegate.
    Again, can i use the solution posted by @calmspeaker?

    Thanks a lot for helping me out! I am really new with MVC and it's a bit complex for newbies.
    Last edited by montylee; 12th December 2008 at 17:35.

  6. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 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
    I was thinking about using the CheckStateRole. Please elaborate on the usage of the same. As i mentioned the column containing checkbox is not in the database. I get only the 1st 3 columns from the database and then add checkboxes to the 4th column, The checkboxes are meant for adding songs to a playlist and have nothing to do with the song database.
    You don't have to put them in a separate column. Place them alongside the actual data in column 0. For this to work you need to reimplement QAbstractItemModel::flags() to return ItemIsUserCheckable among other flags for indexes having column()==0. Then you need to return true or false from the data() method of the model for the CheckStateRole and allow the model to be editable by allowing setData() to change the CheckStateRole of your model. The rest will be taken care of automatically.

    So, if i use the following code in the data() function of the model, will it work?
    Qt Code:
    1. if(index.column() == 3) // 4th column for checkboxes
    2. {
    3. if (role == Qt::DisplayRole)
    4. {
    5. QCheckBox *cbox;
    6. return cbox;
    7. }
    8. }
    9. //.......
    10. }
    To copy to clipboard, switch view to plain text mode 
    No, this is wrong. You don't return widgets from the model.

    i am not sure about it. In QTableWidget, we can just set the checkstate property to get a checkbox but in QTableView, i am not sure if i have to create a QCheckBox or not.
    It's the same here - you need to set appropriate attributes. There is no real checkbox anywhere, it is mimicked by the item delegate.

    And how will i get the events for the checkbox?
    You don't. There is no need to.

    Basically i want to get the row number or track name when user clicks on a checkbox. So, whenever user selects/deselects a checkbox, i need to get the track name and add/delete it from the playlist.
    Connect to the dataChanged() signal of the model and check the CheckStateRole of the appropriate index - it will either be true or false depending on the state of the "checkbox" (remember there is no real checkbox there although you see one).

    Also, since from the database i'll get only 3 columns, how will i add another column to the model without disturbing the database? I am using model->insertColumn() in the code which i posted in my first post.
    You won't - you will display the checkbox in the first column. It looks better this way.

    I am not familiar with delegates, so the solution posted by @calmspeaker looks ok to me. I don't need to modify the database from the GUI, so i can avoid using the delegates.
    You already are using delegates. It's only a matter of how much control you want to have over the mechanism of displaying your data in views. The standard delegate takes the DisplayRole and renders it to the target widget with DecorationRole used as the icon. If you want something else, you subclass the default delegate and extend/substitute the painting routine.

    Again, can i use the solution posted by @calmspeaker?
    There is more than one solution for most problems. Choose the one you are most comfortable with.

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

    montylee (15th December 2008)

  8. #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

    hey thanks a lot for answering my queries!
    Actual i can't change the location of the checkbox as it has already been defined as to be displayed in a separate column after the song time column.

    You don't have to put them in a separate column. Place them alongside the actual data in column 0. For this to work you need to reimplement QAbstractItemModel::flags() to return ItemIsUserCheckable among other flags for indexes having column()==0. Then you need to return true or false from the data() method of the model for the CheckStateRole and allow the model to be editable by allowing setData() to change the CheckStateRole of your model. The rest will be taken care of automatically.
    As per my requirement, i am thinking of first inserting a new column which is not in the database so it's not part of the mode initially. So, i'll use insertColumn() to insert the 4th column. Then i'll reimplement the flags() function and return ItemIsUserCheckable for the 4th column as you suggested.

    So, if i use the following code in the data() function of the model, will it work?
    Qt Code:

    1.
    if(index.column() == 3) // 4th column for checkboxes
    2.
    {
    3.
    if (role == Qt:isplayRole)
    4.
    {
    5.
    QCheckBox *cbox;
    6.
    return cbox;
    7.
    }
    8.
    }
    9.
    //.......
    10.
    }
    No, this is wrong. You don't return widgets from the model.
    Here, i'll return just true and false based on the CheckStateRole.

    Just wanted to know more about displaying an icon along with an image in the same field of the model. Suppose i want to display an icon with the song name field. The currently playing track should have an icon next to the track name in addition to the track name. So, is the following code correct:
    Qt Code:

    if(index.column() == column_track)
    {
    if (role == Qt:ecorationRole)
    {
    QIcon *icon = new QIcon(this);
    // Attach image to icon
    return QIcon;
    }
    if (role == Qt:isplayRole)
    {
    return index.data();
    }
    //.......
    }

    So, in the above code, i am returning an icon for the tracks column for DecorationRole and returning the track name for DisplayRole. Will index.data() return the track name or do i need to use some other API?
    Will the above code display both the track name and icon when the application starts up? If i call the data() function explicitly with DecorationRole i'll get a QIcon, so do i need to set the icon in the QTableView column explicitly? And i think you mentioned that i can't return widgets from the model, so how do i display an icon next to the text?

    One more query:
    For rewriting the data() and flags() functions to get the desired functionality i am thinking of subclassing the QSqlTableModel or QSqlQueryModel, will it work or do i have to subclass from QAbstractItemModel? I want to subclass from QSqlTableModel or QSqlQueryModel as i require the database functionality being provided with these classes.
    Last edited by montylee; 15th December 2008 at 16:49.

  9. #7
    Join Date
    Aug 2008
    Location
    Nanjing, China
    Posts
    66
    Thanks
    12
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: A few queries about Model View Programming

    One way to know which type could be returned by data() function is , whether the data type could be converted to QVariant,
    The best way to study MVC in qt is read the qt doc Model/View Programming.You could easily find it in the Qt assistant.
    Wish you have fun in programming in Qt!
    Jerry

  10. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 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

    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

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

    georgep (15th February 2009)

  12. #9
    Join Date
    Jul 2008
    Posts
    47
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: A few queries about Model View Programming

    Just a side question to "A simple rule says - never return a pointer from data(). ".

    How would I return a QList?
    AFAIK the data() returns a copy of the QList. This would be in my case very sad.

    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?

    Docu to QVariant says it has a speed and memory issue.

  13. #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
    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?

  14. #11
    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.

  15. #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

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

  16. #13
    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.

  17. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 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.

  18. #15
    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.

  19. #16
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 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 

  20. #17
    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...

  21. #18
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 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?

  22. #19
    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

  23. #20
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 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.

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.