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. Problem while applying filter on QTableView with a button column
Forum Updated to NodeBB v4.3 + New Features

Problem while applying filter on QTableView with a button column

Scheduled Pinned Locked Moved Solved General and Desktop
18 Posts 3 Posters 4.2k Views 1 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.
  • L Lati

    @JonB It seems then the issue is related to the setIndexWidget() . I missed that setIndexWidget should only be used for static content and thank you for pointing this. I will update the code with QStyledItemDelegate instead and see if it works.

    Thanks again.

    JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by JonB
    #8

    @Lati
    If I'm not mistaken, if @VRonin [call for him to confirm?] sees your setIndexWidget() he will go apoplectic :) He advocates styled item delegates/paint events only..... !

    L 1 Reply Last reply
    0
    • JonBJ JonB

      @Lati
      If I'm not mistaken, if @VRonin [call for him to confirm?] sees your setIndexWidget() he will go apoplectic :) He advocates styled item delegates/paint events only..... !

      L Offline
      L Offline
      Lati
      wrote on last edited by Lati
      #9

      @JonB :) I am sorry for him but unfortunately such beginners exist in every coding community like me. Let's see if @VRonin forgives me :D

      (though I guess TableView's column headers are programmed properly! ;) )

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

        Who summoned my whrath?!

        In this case you have to fill a QStyleOptionButton in the delegate's paint method and simply react to the clicked event of the view. It's just a bit tedious to type in the code but it's not complicated

        "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

        L 1 Reply Last reply
        2
        • VRoninV VRonin

          Who summoned my whrath?!

          In this case you have to fill a QStyleOptionButton in the delegate's paint method and simply react to the clicked event of the view. It's just a bit tedious to type in the code but it's not complicated

          L Offline
          L Offline
          Lati
          wrote on last edited by
          #11

          @VRonin Ask for your forgiveness your highness! :)

          Thank you for your suggestion, can you please show me an example code or a sample project?

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

            Something like this

            class ButtonDelegate : public QStyledItemDelegate {
                Q_OBJECT
                Q_DISABLE_COPY(ButtonDelegate)
            private:
            	QStyleOptionButton prepareButtonOption(const QStyleOptionViewItem &option) const{
            		QStyleOptionButton buttonOption;
                    buttonOption.text = tr("Add Interval");
                    buttonOption.rect = option.rect
                    buttonOption.features = QStyleOptionButton::None;
                    buttonOption.direction = option.direction;
                    buttonOption.fontMetrics = option.fontMetrics;
                    buttonOption.palette = option.palette;
                    buttonOption.styleObject = option.styleObject;
            		return buttonOption;
            	}
            public:
                explicit ButtonDelegate(QObject* parent = Q_NULLPTR)
                    :QStyledItemDelegate(parent)
                {}
            
                void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
                    Q_ASSERT(index.isValid());
                    QStyleOptionViewItem opt = option;
                    initStyleOption(&opt, index);
                    const QWidget *widget = option.widget;
                    QStyle *style = widget ? widget->style() : QApplication::style();
                    QStyleOptionButton btnOption=prepareButtonOption(opt);
                    style->drawControl(QStyle::CE_PushButton, &btnOption, painter, widget);
                }
            	QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
            		QStyleOptionButton btnOpt=prepareButtonOption(opt);
                    const QSize fntSize = fontMetrics().size(Qt::TextShowMnemonic,btnOpt.text);
            		const QWidget *widget = option.widget;
                    QStyle *style = widget ? widget->style() : QApplication::style();
            		return style->sizeFromContents(CT_PushButton,&btnOpt,fntSize,this);
                }
            }
            

            "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

            JonBJ L 3 Replies Last reply
            2
            • VRoninV VRonin

              Something like this

              class ButtonDelegate : public QStyledItemDelegate {
                  Q_OBJECT
                  Q_DISABLE_COPY(ButtonDelegate)
              private:
              	QStyleOptionButton prepareButtonOption(const QStyleOptionViewItem &option) const{
              		QStyleOptionButton buttonOption;
                      buttonOption.text = tr("Add Interval");
                      buttonOption.rect = option.rect
                      buttonOption.features = QStyleOptionButton::None;
                      buttonOption.direction = option.direction;
                      buttonOption.fontMetrics = option.fontMetrics;
                      buttonOption.palette = option.palette;
                      buttonOption.styleObject = option.styleObject;
              		return buttonOption;
              	}
              public:
                  explicit ButtonDelegate(QObject* parent = Q_NULLPTR)
                      :QStyledItemDelegate(parent)
                  {}
              
                  void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
                      Q_ASSERT(index.isValid());
                      QStyleOptionViewItem opt = option;
                      initStyleOption(&opt, index);
                      const QWidget *widget = option.widget;
                      QStyle *style = widget ? widget->style() : QApplication::style();
                      QStyleOptionButton btnOption=prepareButtonOption(opt);
                      style->drawControl(QStyle::CE_PushButton, &btnOption, painter, widget);
                  }
              	QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
              		QStyleOptionButton btnOpt=prepareButtonOption(opt);
                      const QSize fntSize = fontMetrics().size(Qt::TextShowMnemonic,btnOpt.text);
              		const QWidget *widget = option.widget;
                      QStyle *style = widget ? widget->style() : QApplication::style();
              		return style->sizeFromContents(CT_PushButton,&btnOpt,fntSize,this);
                  }
              }
              
              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #13

              @VRonin
              That is indeed a lot of code compared against the original setIndexWidget(item, new QPushButton("..."));! Makes me want to stick with that approach ;-)

              VRoninV L 2 Replies Last reply
              0
              • JonBJ JonB

                @VRonin
                That is indeed a lot of code compared against the original setIndexWidget(item, new QPushButton("..."));! Makes me want to stick with that approach ;-)

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

                @JonB said in Problem while applying filter on QTableView with a button column:

                Makes me want to stick with that approach

                Teasing eh?! Cheeky sod!

                "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

                JonBJ 1 Reply Last reply
                0
                • VRoninV VRonin

                  @JonB said in Problem while applying filter on QTableView with a button column:

                  Makes me want to stick with that approach

                  Teasing eh?! Cheeky sod!

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #15

                  @VRonin
                  I'm not the one who is teasing! When I discovered them I was quite happy with setIndexWidget() and whatever other methods which let you set a widget in a table etc. Simple, easy to use. Then you came along and put the fear of God into me & anyone else who chooses to use this approach, saying we would run out of memory and be damned for eternity, be kicked out of the EU, etc. ;-) So now I wouldn't dare use them....

                  1 Reply Last reply
                  0
                  • VRoninV VRonin

                    Something like this

                    class ButtonDelegate : public QStyledItemDelegate {
                        Q_OBJECT
                        Q_DISABLE_COPY(ButtonDelegate)
                    private:
                    	QStyleOptionButton prepareButtonOption(const QStyleOptionViewItem &option) const{
                    		QStyleOptionButton buttonOption;
                            buttonOption.text = tr("Add Interval");
                            buttonOption.rect = option.rect
                            buttonOption.features = QStyleOptionButton::None;
                            buttonOption.direction = option.direction;
                            buttonOption.fontMetrics = option.fontMetrics;
                            buttonOption.palette = option.palette;
                            buttonOption.styleObject = option.styleObject;
                    		return buttonOption;
                    	}
                    public:
                        explicit ButtonDelegate(QObject* parent = Q_NULLPTR)
                            :QStyledItemDelegate(parent)
                        {}
                    
                        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
                            Q_ASSERT(index.isValid());
                            QStyleOptionViewItem opt = option;
                            initStyleOption(&opt, index);
                            const QWidget *widget = option.widget;
                            QStyle *style = widget ? widget->style() : QApplication::style();
                            QStyleOptionButton btnOption=prepareButtonOption(opt);
                            style->drawControl(QStyle::CE_PushButton, &btnOption, painter, widget);
                        }
                    	QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
                    		QStyleOptionButton btnOpt=prepareButtonOption(opt);
                            const QSize fntSize = fontMetrics().size(Qt::TextShowMnemonic,btnOpt.text);
                    		const QWidget *widget = option.widget;
                            QStyle *style = widget ? widget->style() : QApplication::style();
                    		return style->sizeFromContents(CT_PushButton,&btnOpt,fntSize,this);
                        }
                    }
                    
                    L Offline
                    L Offline
                    Lati
                    wrote on last edited by
                    #16

                    @VRonin Thanks for the code! I will try to implement after few modifications.

                    1 Reply Last reply
                    0
                    • JonBJ JonB

                      @VRonin
                      That is indeed a lot of code compared against the original setIndexWidget(item, new QPushButton("..."));! Makes me want to stick with that approach ;-)

                      L Offline
                      L Offline
                      Lati
                      wrote on last edited by
                      #17

                      @JonB Absolutely agree and disagree :) Wish filtering would work with setIndexWidget and I wouldn't loose time to implement the same thing with 100x more codes
                      But for static tables, I will use setIndexWidget :)

                      1 Reply Last reply
                      0
                      • VRoninV VRonin

                        Something like this

                        class ButtonDelegate : public QStyledItemDelegate {
                            Q_OBJECT
                            Q_DISABLE_COPY(ButtonDelegate)
                        private:
                        	QStyleOptionButton prepareButtonOption(const QStyleOptionViewItem &option) const{
                        		QStyleOptionButton buttonOption;
                                buttonOption.text = tr("Add Interval");
                                buttonOption.rect = option.rect
                                buttonOption.features = QStyleOptionButton::None;
                                buttonOption.direction = option.direction;
                                buttonOption.fontMetrics = option.fontMetrics;
                                buttonOption.palette = option.palette;
                                buttonOption.styleObject = option.styleObject;
                        		return buttonOption;
                        	}
                        public:
                            explicit ButtonDelegate(QObject* parent = Q_NULLPTR)
                                :QStyledItemDelegate(parent)
                            {}
                        
                            void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
                                Q_ASSERT(index.isValid());
                                QStyleOptionViewItem opt = option;
                                initStyleOption(&opt, index);
                                const QWidget *widget = option.widget;
                                QStyle *style = widget ? widget->style() : QApplication::style();
                                QStyleOptionButton btnOption=prepareButtonOption(opt);
                                style->drawControl(QStyle::CE_PushButton, &btnOption, painter, widget);
                            }
                        	QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
                        		QStyleOptionButton btnOpt=prepareButtonOption(opt);
                                const QSize fntSize = fontMetrics().size(Qt::TextShowMnemonic,btnOpt.text);
                        		const QWidget *widget = option.widget;
                                QStyle *style = widget ? widget->style() : QApplication::style();
                        		return style->sizeFromContents(CT_PushButton,&btnOpt,fntSize,this);
                            }
                        }
                        
                        L Offline
                        L Offline
                        Lati
                        wrote on last edited by Lati
                        #18

                        @VRonin It is implemented, working good. However, I have an issue. When setItemDelegateForColumn is used, all created buttons at the column have the same properties (the last row button's properties). How will I know the row number of the button I clicked?

                        I create the buttons as following:

                        ButtonDelegateTableView * addIntervalButton =
                                new ButtonDelegateTableView(ui->tableView,
                                                            project,
                                                            wellName,
                                                            rowNumber);
                        

                        And, when I clicked on the button at the first row, I get the properties (well name, row number etc.) of the last row buttons.

                        Capture.PNG

                        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