Solved How to change QStyleOptionButton's text?
-
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 theQItemDelegate::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
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?
-
- you should subclass
QStyledItemDelegate
, notQItemDelegate
- 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 useQAbstractItemView::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"); } };
- you should subclass
-
@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 -
@VRonin
I got it ,thanks