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. How to change QStyleOptionButton's text?

How to change QStyleOptionButton's text?

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 2 Posters 1.3k 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.
  • qazaq408Q Offline
    qazaq408Q Offline
    qazaq408
    wrote on last edited by VRonin
    #1

    Now There 's a QTableView that show some data. At last column of the table,the value's type is bool,it's a switch of a kind of device.
    Thanks to the programme need to allow user to control the device,so I put a QPushButton ont the last column of QTableView by delegate. According to my design,the button's text is "Launch",when user click this button ,the button's text is "Stop:,if user click this button again ,the button's text will change to "Launch".
    So,I plain to use QItemDelegate and QStyleOptionButton,I produce a class that's name is SwitchButton inheriten QItemDelegate.
    First,I implement the QItemDelegate::paint();

    void SwitchDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
    {
        if(index.column() == 3)
        {
            QStyleOptionButton* btn = new QStyleOptionButton;
            btn->rect = option.rect;
            btn->text = tr("Launch");
            btn->state |= QStyle::State_Enabled;
            QApplication::style()->drawControl(QStyle::CE_PushButton,btn,painter);
            const_cast<SwitchDelegate*>(this)->switchButton_Map.insert(index,btn);
        }
        else
            QItemDelegate::paint(painter,option,index);
    }
    

    So far here ,everything is OK,the programme looks like this
    alt text

    Second,I replement editorEvent() for user can change the button's text by click the button.

    bool SwitchDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
    {
        if(event->type() == QEvent::MouseButtonPress && static_cast<QMouseEvent*>(event)->button() == Qt::LeftButton)
        {
            if(switchButton_Map.keys().contains(index))
            {
                QStyleOptionButton* btn = switchButton_Map.value(index);
                if(btn->text == tr("Launch"))  //here,nothing to change...
                    btn->text = tr("Stop");
                else if(btn->text == tr("Stop"))
                    btn->text = tr("Launch");
    
            }
        }
        return QItemDelegate::editorEvent(event,model,option,index);
    }
    

    Arccording to my original design,the button's text will be changed when user clicked the button,but in fact ,there's no change when I click the button.

    How to change the text of QStyleOptionButton?

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #2
      • you should subclass QStyledItemDelegate, not QItemDelegate
      • you are leaking the QStyleOptionButton
      • if(index.column() == in a delegate is bad design. this ties the delegate to the particular model you are using. You should use QAbstractItemView::setItemDelegateForColumn instead
      • you don't need to reimplement editorEvent you can just connect to clicked
      • you need to store the changed boolean value in the model
      class SwitchDelegate : public QStyledItemDelegate{
          Q_OBJECT
          Q_DISABLE_COPY(SwitchDelegate)
      public:
          explicit SwitchDelegate(QObject* parent = Q_NULLPTR) 
              : QStyledItemDelegate(parent)
          {}
          void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const Q_DECL_OVERRIDE
          {
              QStyleOptionButton btn;
              btn.rect = option.rect;
              btn.text = textForValue(index.data().toBool());
              btn.state |= QStyle::State_Enabled;
              (option.widget ? option.widget.style() : QApplication::style())->drawControl(QStyle::CE_PushButton,&btn,painter);
          }
          QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
              return new QPushButton(parent);
          }
          void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE{
              QPushButton* button = qobject_cast<QPushButton*>(editor);
              Q_ASSERT(button);
              const bool started = index.data().toBool();
              button->setProperty("Started",started);
              button->setText(textForValue(started));
              QObject::connect(button,&QPushButton::clicked,button,[button]()->void{
                  const bool started = button->property("Started").toBool();
                  button->setProperty("Started",!started);
                  button->setText(textForValue(!started));
              });
          }
          void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE{
              QPushButton* button = qobject_cast<QPushButton*>(editor);
              Q_ASSERT(button);
              model->setData(index,button->property("Started").toBool());
          }
      private:
          QString textForValue(bool val) const {
              if(val)
                  return tr("Stop");
              return tr("Launch");
          }
      };
      

      "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

      qazaq408Q 2 Replies Last reply
      5
      • VRoninV VRonin
        • you should subclass QStyledItemDelegate, not QItemDelegate
        • you are leaking the QStyleOptionButton
        • if(index.column() == in a delegate is bad design. this ties the delegate to the particular model you are using. You should use QAbstractItemView::setItemDelegateForColumn instead
        • you don't need to reimplement editorEvent you can just connect to clicked
        • you need to store the changed boolean value in the model
        class SwitchDelegate : public QStyledItemDelegate{
            Q_OBJECT
            Q_DISABLE_COPY(SwitchDelegate)
        public:
            explicit SwitchDelegate(QObject* parent = Q_NULLPTR) 
                : QStyledItemDelegate(parent)
            {}
            void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const Q_DECL_OVERRIDE
            {
                QStyleOptionButton btn;
                btn.rect = option.rect;
                btn.text = textForValue(index.data().toBool());
                btn.state |= QStyle::State_Enabled;
                (option.widget ? option.widget.style() : QApplication::style())->drawControl(QStyle::CE_PushButton,&btn,painter);
            }
            QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
                return new QPushButton(parent);
            }
            void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE{
                QPushButton* button = qobject_cast<QPushButton*>(editor);
                Q_ASSERT(button);
                const bool started = index.data().toBool();
                button->setProperty("Started",started);
                button->setText(textForValue(started));
                QObject::connect(button,&QPushButton::clicked,button,[button]()->void{
                    const bool started = button->property("Started").toBool();
                    button->setProperty("Started",!started);
                    button->setText(textForValue(!started));
                });
            }
            void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE{
                QPushButton* button = qobject_cast<QPushButton*>(editor);
                Q_ASSERT(button);
                model->setData(index,button->property("Started").toBool());
            }
        private:
            QString textForValue(bool val) const {
                if(val)
                    return tr("Stop");
                return tr("Launch");
            }
        };
        
        qazaq408Q Offline
        qazaq408Q Offline
        qazaq408
        wrote on last edited by qazaq408
        #3

        @VRonin
        Thank you very much.
        But there's till a problem.....when user open QTableView first,they will look a button on the one column of the table,in my hope,user can change the switch by click the button.but in fact ,user only change switch after doubleClick the button.How to show the button when user click the button rather than doubleClick

        1 Reply Last reply
        0
        • VRoninV VRonin
          • you should subclass QStyledItemDelegate, not QItemDelegate
          • you are leaking the QStyleOptionButton
          • if(index.column() == in a delegate is bad design. this ties the delegate to the particular model you are using. You should use QAbstractItemView::setItemDelegateForColumn instead
          • you don't need to reimplement editorEvent you can just connect to clicked
          • you need to store the changed boolean value in the model
          class SwitchDelegate : public QStyledItemDelegate{
              Q_OBJECT
              Q_DISABLE_COPY(SwitchDelegate)
          public:
              explicit SwitchDelegate(QObject* parent = Q_NULLPTR) 
                  : QStyledItemDelegate(parent)
              {}
              void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const Q_DECL_OVERRIDE
              {
                  QStyleOptionButton btn;
                  btn.rect = option.rect;
                  btn.text = textForValue(index.data().toBool());
                  btn.state |= QStyle::State_Enabled;
                  (option.widget ? option.widget.style() : QApplication::style())->drawControl(QStyle::CE_PushButton,&btn,painter);
              }
              QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
                  return new QPushButton(parent);
              }
              void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE{
                  QPushButton* button = qobject_cast<QPushButton*>(editor);
                  Q_ASSERT(button);
                  const bool started = index.data().toBool();
                  button->setProperty("Started",started);
                  button->setText(textForValue(started));
                  QObject::connect(button,&QPushButton::clicked,button,[button]()->void{
                      const bool started = button->property("Started").toBool();
                      button->setProperty("Started",!started);
                      button->setText(textForValue(!started));
                  });
              }
              void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE{
                  QPushButton* button = qobject_cast<QPushButton*>(editor);
                  Q_ASSERT(button);
                  model->setData(index,button->property("Started").toBool());
              }
          private:
              QString textForValue(bool val) const {
                  if(val)
                      return tr("Stop");
                  return tr("Launch");
              }
          };
          
          qazaq408Q Offline
          qazaq408Q Offline
          qazaq408
          wrote on last edited by
          #4

          @VRonin
          I got it ,thanks

          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