Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QItemDelegate with QTableWidget, access problem
QtWS25 Last Chance

QItemDelegate with QTableWidget, access problem

Scheduled Pinned Locked Moved Solved General and Desktop
qitemdelegateqtablewidgeteditor
6 Posts 2 Posters 3.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    michelson
    wrote on last edited by michelson
    #1

    Hello,
    lets say you have a QTableWidget with two colums and you would like to have custom behaviour on cell click implemented - in this case it would be combo box popup BUT the second column content depends on first column choice.
    Example:
    first column combo box content -> { letter, number}
    second column combo box content -> { a,b,c, 1, 2, 3}
    So if you pick {letter} in first colum the second column available choices would be {a,b,c} (analogical behaviour with number)
    I assume you have to reimplement QItemDelegate::createEditor(...) function however i dont know how to achive specified behaviour.
    NOTE:

    1. I dont want to paste tons of code here so for an example of custom QItemDelegates i provide this link:
      http://programmingexamples.net/wiki/Qt/Delegates/ComboBoxDelegate
      or you can try checking out Qt Example of StarDelegate here:
      http://doc.qt.io/qt-5/qtwidgets-itemviews-stardelegate-example.html
    2. I was trying to retrive specified (first column choice) from the parent pointer which is passed to createEditor function but it seems that my parent is not exactly QTableWidget
    1 Reply Last reply
    0
    • M Offline
      M Offline
      michelson
      wrote on last edited by michelson
      #2

      For anyone who is interested in solution i found:
      parent of the parent pointer passed to QItemDelegate::createEditor(...) is the QTableWidget we were looking for so

      QTableWidget *tbl = static_cast<QTableWidget*>(parent->parent());
      tbl->item(0,0)->text(); 
      

      solves the problem (for me at least).

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        Using static_cast is a bad idea here, there's absolutely no checks done. For QObject derived classes, you should use qobject_cast and check that you have a valid pointer returned.

        Anyway, back for your problem, what you are doing is not clean at all. You should rather re-implement the setEditorData function to populate your QComboBox. You'll get an QModelIndex which will give you access to the QTableWidget's model and from there you can access the data you need without resorting to tricks like retrieving the parent of the parent of the delegate.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        M 1 Reply Last reply
        0
        • SGaistS SGaist

          Hi,

          Using static_cast is a bad idea here, there's absolutely no checks done. For QObject derived classes, you should use qobject_cast and check that you have a valid pointer returned.

          Anyway, back for your problem, what you are doing is not clean at all. You should rather re-implement the setEditorData function to populate your QComboBox. You'll get an QModelIndex which will give you access to the QTableWidget's model and from there you can access the data you need without resorting to tricks like retrieving the parent of the parent of the delegate.

          M Offline
          M Offline
          michelson
          wrote on last edited by
          #4

          @SGaist Thanks for your reply! I thought there may be some, as you said, "cleaner" solution so i will definetly try to rewrite my code with the tips you gave. However have an eye on this thread because i will probably paste my work here and mayby then you can add some final pieces of advice to make it clean and correctly written.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            michelson
            wrote on last edited by
            #5

            @SGaist here is what i created, it is working correctly and i hope it is written correctly as well :)

            // reimplemented createEditor(...) func
            QWidget *CustomDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
            {
                // colum 0 - populate combobox with predeterminated data
                if(index.column() == 0)
                {
                    QComboBox* editor = new QComboBox(parent);
                    Q_FOREACH(QString str, predeterminatedData) //predeterminatedData === QStringList in my case
                        editor->addItem(str);
                    return editor;
                }
                // column 1 - content is column-zero dependent, i deal with it in setEditorData
                if(index.column() == 1)
                {
                    QComboBox* editor = new QComboBox(parent);
                    return editor;
                }
               // default editor elsewhere
                return QItemDelegate::createEditor(parent, option, index);
            }
            
            // reimplemented setEditorData(...) func
            void CustomDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
            {
                const QAbstractItemModel *model = index.model();
                QComboBox *comboBox = static_cast<QComboBox*>(editor);
                // editing 1st column?
                if(index.column() == 1)
                {
                    // in my case there can be 2 options in the first column so i  check if its first option
                    if(model->data(model->index(index.row(), 0),Qt::DisplayRole).toString().contains("FIRST"))
                    {
                        Q_FOREACH(QString str, itemsForFirstOption) // itemsForFirstOption === QStringList 
                            comboBox->addItem(str,Qt::DisplayRole);
                    }
                    else // second option
                    {
                        Q_FOREACH(QString str, itemsForSecondOption) // itemsForSecondOption === QStringList
                            comboBox->addItem(str,Qt::DisplayRole);
                    }
                }
            }
            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              QComboBox has a addItems where you can directly use your QStringList, so no need for the loops. And again, you should not use static_cast like that, use object_cast.

              You're lucky it's not crashing because you only handle column 1 where you know you create a QComboBox. You should move these two lines under the if protection.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved