Results 1 to 11 of 11

Thread: How to create dependency between 2 columns using combobox delegates in MVC

  1. #1
    uzairsaeed702 Guest

    Default How to create dependency between 2 columns using combobox delegates in MVC

    Hello,

    I have a 5 column Model inherited by "QAbstractTableModel" because of QTableView as View. The last two columns contains combo boxes which are populated through their delegates inherited by "QStyledItemDelegate". Everything is working fine independently.

    Next Task:
    Column 4 contains some mode which is related to column 5 in terms of respective functions,(refer the below figure) e.g. if I select some item in the (col-4) combo box, it will change/create the col-5 combo box according to the provided functions from Model. Which means every time when I receive the signal of datachange in column 4, it has to call the createWidget function from the delegate class in order to create a new combo box and its items. I tried some ways to call createWidget manually when I have received the datachange but as the Model is running with specific index.col I can not change the data of column 5 while changing settings in column 4.

    ComboBox.jpg

    above figure shows the example what i want to do , Like if I select the Decrement mode it will fetch the data(done) and create a new combo box or update the data of the combo box in column 5. I have tried many logic and algo to change things from setEditorData & setModelData though the only problem is that index is at column 4 so couldn't even do the qobject_cast.

    Please share your experience in this regard or maybe I am doing something wrong.
    Last edited by uzairsaeed702; 2nd March 2015 at 13:03.

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to create dependency between 2 columns using combobox delegates in MVC

    How did you put combo boxes in table view, did you use setIndexWidget()?
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  3. #3
    uzairsaeed702 Guest

    Default Re: How to create dependency between 2 columns using combobox delegates in MVC

    Via combo box delegate class
    inherited by "QStyledItemDelegate"

  4. #4
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to create dependency between 2 columns using combobox delegates in MVC

    So how is that you are doing? Painting the combo box from delegate and when clicked creating an editor for the item using delegate?
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  5. #5
    uzairsaeed702 Guest

    Default Re: How to create dependency between 2 columns using combobox delegates in MVC

    No, I am creating combo box in QWidget *ComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option , const QModelIndex &index ) const method while i can check the "QModelIndex &index" in prder to check the specific column. Everything is working fine but only problem is that i have to make some logic that when i change something in column 4 then respectively columns 5 combo box has to be changed also.

  6. #6
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to create dependency between 2 columns using combobox delegates in MVC

    When the column 4 QComboBox is edited and data is submitted to the model, the model internally (in setData()) has to adjust the data for the column 5 and emit dataChanged() signal for the column 5 model index.
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  7. #7
    uzairsaeed702 Guest

    Default Re: How to create dependency between 2 columns using combobox delegates in MVC

    Well i am setting the model via setData() by void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const function but when i send the data to the model it was currently having the pointer of column 4 not column 5. QcomboBox is working

    e.g. see below Model
    Qt Code:
    1. bool TableModel::setData(const QModelIndex & index, const QVariant &value, int role)
    2. {
    3. int row = index.row();
    4. int col = index.column();
    5. QMap<QString, QVariant> qMapPair = p_tagSimItems->getItemsMap().at(row);
    6.  
    7. if(index.isValid() && role == Qt::EditRole)
    8. {
    9. switch(col) {
    10. case 0 :
    11. {
    12. qMapPair.insert("a",value.toString());
    13. p_tagSimItems->setItemMap(row,qMapPair);
    14. emit (dataChanged(index , index));
    15. return true;
    16. }
    17. break;
    18. case 1 :
    19. {
    20. qMapPair.insert("b",p_tagSimItems->isValidEnteredType(value.toString()));
    21. p_tagSimItems->setItemMap(row,qMapPair);
    22. emit (dataChanged(index , index));
    23. return true;
    24. }
    25. break;
    26. case 2 :
    27. {
    28. qMapPair.insert("c",value.toString().toUShort(0,10));
    29. p_tagSimItems->setItemMap(row,qMapPair);
    30. emit (dataChanged(index , index));
    31. return true;
    32. }
    33. break;
    34.  
    35. case 3 :
    36. { [B]// the problem is here when model receive the signal from delegate in column 4 then i have to change the column 5 also manually which seems not possible because model is on column 4 .[/B]
    37. if (value.toString().toUShort(0,10) < 256)
    38. {
    39. qMapPair.insert("d",value.toString().toUShort(0,10));
    40. }else
    41. {
    42. qMapPair.insert("d",0);
    43. }
    44. p_tagSimItems->setItemMap(row,qMapPair);
    45. emit (dataChanged(index , index));
    46. return true;
    47. }
    48. break;
    49. case 4 :
    50. {
    51. if (value.toString().toUShort(0,10) < 256)
    52. {
    53. qMapPair.insert("e",value.toString().toUShort(0,10));
    54. }else
    55. {
    56. qMapPair.insert("e",0);
    57. }
    58. p_tagSimItems->setItemMap(row,qMapPair);
    59. emit (dataChanged(index , index));
    60. return true;
    61. }
    62. break;
    63. default :
    64. break;
    65. }
    66. }
    67. return false;
    68. }
    To copy to clipboard, switch view to plain text mode 

    After this, model call the
    Qt Code:
    1. void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    To copy to clipboard, switch view to plain text mode 
    function in order to set the Index of the combo box.
    Last edited by uzairsaeed702; 3rd March 2015 at 10:30.

  8. #8
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to create dependency between 2 columns using combobox delegates in MVC

    // the problem is here when model receive the signal from delegate in column 4 then i have to change the column 5 also manually which seems not possible because model is on column 4 .
    When inside setData() for column 4, you could call setData for column 5, you just need to create a new index (by calling QAbstractItemModel::createIndex) for column 5 and then pass it to the setData();
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  9. #9
    uzairsaeed702 Guest

    Default Re: How to create dependency between 2 columns using combobox delegates in MVC

    Quote Originally Posted by Santosh Reddy View Post
    When inside setData() for column 4, you could call setData for column 5, you just need to create a new index (by calling QAbstractItemModel::createIndex) for column 5 and then pass it to the setData();
    Can you give me a example ?

  10. #10
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to create dependency between 2 columns using combobox delegates in MVC

    Here you go, run this code.

    I used delegate (because I used standard model) but you could do the similar in the your custom model.

    Qt Code:
    1. #include <QtWidgets>
    2.  
    3. class Delegate : public QStyledItemDelegate
    4. {
    5. public:
    6. explicit Delegate(QObject * parent = 0) : QStyledItemDelegate(parent) {}
    7.  
    8. QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
    9. {
    10. QComboBox * widget = new QComboBox(parent);
    11.  
    12. widget->addItems(index.data(Qt::UserRole+1).toStringList());
    13.  
    14. return widget;
    15. }
    16.  
    17. void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const
    18. {
    19. if(index.column() == 0)
    20. {
    21. QComboBox * widget = dynamic_cast<QComboBox *>(editor);
    22.  
    23. if(widget)
    24. {
    25. QString country = widget->currentText();
    26.  
    27. QVariant russia = QStringList() << "Moscow" << "Saint Petersburg" << "Novosibirsk" << "Yekaterinburg";
    28. QVariant canada = QStringList() << "Toronto" << "Parliament Hill" << "Quebec" << "Montreal";
    29. QVariant china = QStringList() << "Shanghai" << "Beijing" << "Chongqing" << "Hong Kong";
    30. QVariant states = QStringList() << "New York City" << "Los Angeles" << "Chicago" << "Houston";
    31.  
    32. QModelIndex nextColumnIndex = model->index(index.row(), 1);
    33.  
    34. if(country == "Russia")
    35. {
    36. model->setData(nextColumnIndex, russia, Qt::UserRole+1);
    37. }
    38. else if(country == "Canada")
    39. {
    40. model->setData(nextColumnIndex, canada, Qt::UserRole+1);
    41. }
    42. else if(country == "China")
    43. {
    44. model->setData(nextColumnIndex, china, Qt::UserRole+1);
    45. }
    46. else if(country == "United States")
    47. {
    48. model->setData(nextColumnIndex, states, Qt::UserRole+1);
    49. }
    50.  
    51. model->setData(index, country);
    52. model->setData(nextColumnIndex, "Select City Again");
    53. }
    54. widget->addItems(index.data(Qt::UserRole+1).toStringList());
    55. }
    56. else
    57. {
    58. QStyledItemDelegate::setModelData(editor, model, index);
    59. }
    60. }
    61. };
    62.  
    63. int main(int argc, char *argv[])
    64. {
    65. QApplication app(argc, argv);
    66.  
    67. QTableView table;
    68. QStandardItemModel model(4, 2);
    69.  
    70. for (int row = 0; row < 4; row++)
    71. {
    72. QStandardItem *item = new QStandardItem(QString("Select Country").arg(row).arg(0));
    73. item->setData(QStringList() << "Russia" << "Canada" << "China" << "United States",Qt::UserRole+1);
    74. model.setItem(row, 0, item);
    75.  
    76. item = new QStandardItem(QString("Select City").arg(row).arg(1));
    77. item->setData(QStringList());
    78. model.setItem(row, 1, item);
    79. }
    80.  
    81. table.setModel(&model);
    82. table.setItemDelegate(new Delegate(&model));
    83. table.show();
    84.  
    85. return app.exec();
    86. }
    To copy to clipboard, switch view to plain text mode 
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

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


  12. #11
    uzairsaeed702 Guest

    Default Re: How to create dependency between 2 columns using combobox delegates in MVC

    Quote Originally Posted by Santosh Reddy View Post
    Here you go, run this code.

    I used delegate (because I used standard model) but you could do the similar in the your custom model.

    Qt Code:
    1. QModelIndex nextColumnIndex = model->index(index.row(), 1);
    To copy to clipboard, switch view to plain text mode 

    Santosh Reddy thanks alot for the code but in custom model its difficult to examine the problem .Your hint for AbstractItemModel::createIndex worked like charm !!! . I have just inserted two line of code in model and few lines of code in my delegate class and work done.

    Qt Code:
    1. QModelIndex changeRequest = createIndex(row,4);
    2. setData(changeRequest ,Qt::EditRole);
    To copy to clipboard, switch view to plain text mode 

    Above was my modification ,

    Thanks again Santosh

    Problem Solved (Y)

Similar Threads

  1. Replies: 2
    Last Post: 28th June 2014, 08:21
  2. How to create a color bar in combobox ?
    By likaci in forum Newbie
    Replies: 4
    Last Post: 22nd January 2014, 17:16
  3. Replies: 0
    Last Post: 25th July 2011, 15:11
  4. ComboBox with multiple columns
    By haldrik in forum Qt Programming
    Replies: 7
    Last Post: 11th July 2009, 11:15
  5. Different delegates to different Columns of QTableView.
    By kaushal_gaurav in forum Qt Programming
    Replies: 4
    Last Post: 6th August 2008, 10:17

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.