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. Close ItemDeligate in View when some other Widget is clicked
Qt 6.11 is out! See what's new in the release blog

Close ItemDeligate in View when some other Widget is clicked

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 5 Posters 4.1k Views 2 Watching
  • 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #4

    Hi,

    Is it a custom QStyledItemDelegate ?

    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
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #5

      There should be nothing to code at all to obtain the behaviour you describe.

      • Can you show us your delegate's code?
      • Are you subclassing the view as well?

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      1
      • gde23G Offline
        gde23G Offline
        gde23
        wrote on last edited by
        #6

        @SGais, yes it is a custom delegate.

        Here is my code:

        MyDelegate::MyDelegate(QObject *parent)
            : QStyledItemDelegate(parent)
        {
        
        }
        
        QWidget *MyDelegate::createEditor(QWidget *parent,
            const QStyleOptionViewItem &/* option */,
            const QModelIndex &index ) const
        {
            QWidget *editor;
            QVariant is_checkable = index.model()->data(index, Qt::CheckStateRole);
           
            editor = new QLineEdit(parent);
        
            // if it is checkable add a checkbox
            if(is_checkable.isValid())
            {
                QWidget* widget = new QWidget(parent);
                QHBoxLayout* layout = new QHBoxLayout();
                // to align it with the original one
                layout->setSpacing(3);
                layout->setContentsMargins(3, 0, 0, 0);
        
                QCheckBox* check = new QCheckBox();
                widget->setLayout(layout);
                layout->addWidget(check);
                layout->addWidget(editor);
                widget->setAutoFillBackground(true);
                return widget;
            }
            else
            {
                return editor;
            }
        }
        
        void MyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
        {    
            QString value = index.model()->data(index, Qt::EditRole).toString();
            if(dynamic_cast<QLineEdit*>(editor) == NULL)
            {
                QLineEdit* lineEdit = editor->findChild<QLineEdit*>();
                lineEdit->setText(value);
                lineEdit->setCursorPosition(0); // move cursor to left so we see not only the last decimals but the beginning
                QCheckBox *check = editor->findChild<QCheckBox*>();
                check->setChecked(index.model()->data(index, Qt::CheckStateRole).toBool());
                return;
            }
            else
            {
                QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
                lineEdit->setText(value);
                return;
            }    
        }
        
        void MyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
        {
            QCheckBox* check = editor->findChild<QCheckBox*>();
            if(check != NULL)
            {
                Qt::CheckState value = check->checkState();
                model->setData(index, value, Qt::CheckStateRole);
            }
            
            if(dynamic_cast<QLineEdit*>(editor) == NULL)
            {
                QLineEdit* lineEdit = editor->findChild<QLineEdit*>();
                QString value = lineEdit->text();
                model->setData(index, value, Qt::EditRole);
                break;
            }
            else
            {
                QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
                QString value = lineEdit->text();
                model->setData(index, value, Qt::EditRole);
                return;
            }  
        }
        
        void MyDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
        {
            editor->setGeometry(option.rect);
        }
        
        raven-worxR 1 Reply Last reply
        0
        • gde23G gde23

          @SGais, yes it is a custom delegate.

          Here is my code:

          MyDelegate::MyDelegate(QObject *parent)
              : QStyledItemDelegate(parent)
          {
          
          }
          
          QWidget *MyDelegate::createEditor(QWidget *parent,
              const QStyleOptionViewItem &/* option */,
              const QModelIndex &index ) const
          {
              QWidget *editor;
              QVariant is_checkable = index.model()->data(index, Qt::CheckStateRole);
             
              editor = new QLineEdit(parent);
          
              // if it is checkable add a checkbox
              if(is_checkable.isValid())
              {
                  QWidget* widget = new QWidget(parent);
                  QHBoxLayout* layout = new QHBoxLayout();
                  // to align it with the original one
                  layout->setSpacing(3);
                  layout->setContentsMargins(3, 0, 0, 0);
          
                  QCheckBox* check = new QCheckBox();
                  widget->setLayout(layout);
                  layout->addWidget(check);
                  layout->addWidget(editor);
                  widget->setAutoFillBackground(true);
                  return widget;
              }
              else
              {
                  return editor;
              }
          }
          
          void MyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
          {    
              QString value = index.model()->data(index, Qt::EditRole).toString();
              if(dynamic_cast<QLineEdit*>(editor) == NULL)
              {
                  QLineEdit* lineEdit = editor->findChild<QLineEdit*>();
                  lineEdit->setText(value);
                  lineEdit->setCursorPosition(0); // move cursor to left so we see not only the last decimals but the beginning
                  QCheckBox *check = editor->findChild<QCheckBox*>();
                  check->setChecked(index.model()->data(index, Qt::CheckStateRole).toBool());
                  return;
              }
              else
              {
                  QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
                  lineEdit->setText(value);
                  return;
              }    
          }
          
          void MyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
          {
              QCheckBox* check = editor->findChild<QCheckBox*>();
              if(check != NULL)
              {
                  Qt::CheckState value = check->checkState();
                  model->setData(index, value, Qt::CheckStateRole);
              }
              
              if(dynamic_cast<QLineEdit*>(editor) == NULL)
              {
                  QLineEdit* lineEdit = editor->findChild<QLineEdit*>();
                  QString value = lineEdit->text();
                  model->setData(index, value, Qt::EditRole);
                  break;
              }
              else
              {
                  QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
                  QString value = lineEdit->text();
                  model->setData(index, value, Qt::EditRole);
                  return;
              }  
          }
          
          void MyDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
          {
              editor->setGeometry(option.rect);
          }
          
          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #7

          @gde23
          and i guess it isn't working for editors which are created with a lineedit and checkbox?

          As i said when the editor widget (the pointer returned from createEditor()) receives a focus-out event the editor is closed. Since you compose a editor widget the sub-widget receives the focus-out event without the QStyledItemDelegate recognizing it.

          So you need to make sure that the container widget receives a focus-out event or to close the editor yourself.

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • S Offline
            S Offline
            Slawomir_Piernikowski
            wrote on last edited by Slawomir_Piernikowski
            #8

            I have checked it and it looks like when you edit a ItemDelegate in some cell of in my case the tableView and after you move the mouse arrow to QMainWindow and you clicked once or double then looks like the itemDelegate in the cell does not lose its focus even you resize the main widow. It loses its focus when you click on other widget located on the gui of QMainWindow.
            0_1542884444364_Part.jpg

            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by
              #9

              Can I ask why are you doing this? a QLineEdit and a checkbox is already what you get from the default of QStyledItemDelegate

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              1 Reply Last reply
              0
              • gde23G Offline
                gde23G Offline
                gde23
                wrote on last edited by gde23
                #10

                @raven-worx no it does not work for both cases (with/without the container widget)
                @VRonin: I have tow QTreeViews in the mainwindow. When i click the other QTreeView (or the QTableView that i have in the UI) the editor closes, however clicking some other Widget (e.g. a Button) does not close it
                To your second Question: I'm doing this since I want to add some more features to the Delegate like QSpinBoxes later depending on the type of data a item stores.

                VRoninV 1 Reply Last reply
                0
                • gde23G gde23

                  @raven-worx no it does not work for both cases (with/without the container widget)
                  @VRonin: I have tow QTreeViews in the mainwindow. When i click the other QTreeView (or the QTableView that i have in the UI) the editor closes, however clicking some other Widget (e.g. a Button) does not close it
                  To your second Question: I'm doing this since I want to add some more features to the Delegate like QSpinBoxes later depending on the type of data a item stores.

                  VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by
                  #11

                  @gde23 said in Close ItemDeligate in View when some other Widget is clicked:

                  like QSpinBoxes later depending on the type of data a item stores

                  Again, QStyledItemDelegate already does this by default. You can customise it with QItemEditorFactory and you get the checkbox feature for free as well

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  1 Reply Last reply
                  0
                  • gde23G Offline
                    gde23G Offline
                    gde23
                    wrote on last edited by gde23
                    #12

                    @VRonin: what I need at the end is depending on the Item: QSpinbox or QComboBox or QLineEdit (and maybe some more like a QCombobox besides the QLineEdit in a single cell) depending on the data type the item stores.
                    Can this all be done with the QItemEditorFactory? Then I'll take a look at it.
                    EDIT: as far as I could find out QItemEditorFactory cannot provide a QComboBox for a Item that has multiple choice kind of content (std::map with several entries)
                    EDIT2: so there seems to be some other thing going on. The QTreeView is in a Dockwidget and when I place some pushbutton inside the QDockWidgetContente besides the QTreeView and I press it the editor is closed as it should. However when I click some pushbutton on the MainWindow it is not closed.

                    1 Reply Last reply
                    0
                    • gde23G Offline
                      gde23G Offline
                      gde23
                      wrote on last edited by gde23
                      #13

                      Ok i found out that the problem is somwhere totally else and has nothing to do with the Delegate or the DockWidgets.

                      All my buttons are QToolButtons. When they are clicked the editor does not close.
                      However a QPushButton or also another Widget will close it as

                      I have added these two button to the UI

                          centralWidget()->layout()->addWidget(new QToolButton(centralWidget()));
                          centralWidget()->layout()->addWidget(new QPushButton(centralWidget()));
                      

                      clicking the second one closes the editor in the view. However closing the first one does not.

                      Even more it does not have to do with the view at all. Just a Mainwindow with a QToolButton a QLineEdit and a QPushbutton will demonstrate the behavior.

                      raven-worxR 1 Reply Last reply
                      0
                      • gde23G gde23

                        Ok i found out that the problem is somwhere totally else and has nothing to do with the Delegate or the DockWidgets.

                        All my buttons are QToolButtons. When they are clicked the editor does not close.
                        However a QPushButton or also another Widget will close it as

                        I have added these two button to the UI

                            centralWidget()->layout()->addWidget(new QToolButton(centralWidget()));
                            centralWidget()->layout()->addWidget(new QPushButton(centralWidget()));
                        

                        clicking the second one closes the editor in the view. However closing the first one does not.

                        Even more it does not have to do with the view at all. Just a Mainwindow with a QToolButton a QLineEdit and a QPushbutton will demonstrate the behavior.

                        raven-worxR Offline
                        raven-worxR Offline
                        raven-worx
                        Moderators
                        wrote on last edited by raven-worx
                        #14

                        @gde23
                        you can change this behavior by calling setFocusPolicy(Qt::StrongFocus) on the QToolButton
                        By default QToolButtons only have TabFocus set, whereas QPushButtons don't

                        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                        If you have a question please use the forum so others can benefit from the solution in the future

                        1 Reply Last reply
                        3
                        • gde23G Offline
                          gde23G Offline
                          gde23
                          wrote on last edited by
                          #15

                          Thanks a lot. That solves the problem.

                          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