之前在项目上需要在表格中加入Button是按照以下两个文章的做法:
http://www.cnblogs.com/li-peng/p/3961843.html
http://www.cnblogs.com/li-peng/p/4029885.html
文章的做法是传统通过子类化QItemDelegate类来做的,通过paint函数在某列中画出QPushButton的Style。
但是这么做有一个问题,就是按钮画出来以后,但是拖动QTableView的滚动条的时候,会导致按钮所在的列的部分按钮又消失的问题。
没查到原因,但是最终还是在找到解决方案了。还是子类化QItemDelegate类,但是与之前的两个文章之前的做法有些不同,以下是正确的
代码:
Delegate头文件:
1 #pragma once 2 3 #include4 #include 5 #include 6 7 class QStyleOptionButton; 8 class CTableWidget; 9 class QPushButton;10 11 class AppRepoButtonDelegate : public QStyledItemDelegate12 {13 Q_OBJECT14 15 public:16 17 explicit AppRepoButtonDelegate(QObject *parent = Q_NULLPTR);18 ~AppRepoButtonDelegate();19 public:20 void setText(const QString& text);21 void setStyleSheet(const QString& qss);22 23 signals:24 void buttonClicked(const QModelIndex& index);25 public:26 27 QWidget* createEditor(QWidget *parent,28 const QStyleOptionViewItem &option,29 const QModelIndex &index) const override;30 void paint(QPainter *painter, const QStyleOptionViewItem &option, 31 const QModelIndex &index) const override;32 void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;33 private slots:34 void cellEntered(const QModelIndex& index);35 void slotBtnClicked();36 private:37 CTableWidget * m_table_view;38 bool isOneCellInEditMode;39 QPushButton* m_btn;40 QPersistentModelIndex m_currentEditedCellIndex;41 QString m_btnText;42 QString m_btnQss;43 };
Delegate类的CPP实现文件:
1 #include "AppRepoButtonDelegate.h" 2 3 #include4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 11 #include "CTableWidget.h" 12 13 AppRepoButtonDelegate::AppRepoButtonDelegate(QObject *parent) 14 : QStyledItemDelegate(parent) 15 { 16 CTableWidget *tabView = qobject_cast (parent); 17 if (tabView) 18 { 19 m_table_view = tabView; 20 m_btn = new QPushButton(QStringLiteral(""), m_table_view); 21 m_btn->hide(); 22 m_table_view->setMouseTracking(true); 23 connect(m_table_view, SIGNAL(entered(QModelIndex)), 24 this, SLOT(cellEntered(QModelIndex))); 25 isOneCellInEditMode = false; 26 } 27 } 28 29 AppRepoButtonDelegate::~AppRepoButtonDelegate() 30 { 31 } 32 33 void AppRepoButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 34 { 35 int x, y, width, height; 36 x = option.rect.left() + option.rect.width() / 2 - 20; 37 y = option.rect.top() + 5; 38 width = 60; 39 height = 20; 40 41 m_btn->setGeometry(QRect(x,y,width,height)); 42 m_btn->setText(m_btnText); 43 m_btn->setStyleSheet(m_btnQss); 44 if (option.state == QStyle::State_Selected) 45 painter->fillRect(option.rect, option.palette.highlight()); 46 QPixmap map = QPixmap::grabWidget(m_btn); 47 painter->drawPixmap(x, y, map); 48 } 49 50 QWidget* AppRepoButtonDelegate::createEditor(QWidget *parent, 51 const QStyleOptionViewItem &option, const QModelIndex &index) const 52 { 53 QPushButton * btn = new QPushButton(parent); 54 connect(btn, &QPushButton::clicked, this, &AppRepoButtonDelegate::slotBtnClicked); 55 btn->setText(m_btnText); 56 btn->setStyleSheet(m_btnQss); 57 return btn; 58 } 59 60 void AppRepoButtonDelegate::cellEntered(const QModelIndex& index) 61 { 62 if (index.column() == 6 || index.column() == 7) 63 { 64 if (isOneCellInEditMode) 65 { 66 m_table_view->closePersistentEditor(m_currentEditedCellIndex); 67 } 68 m_table_view->openPersistentEditor(index); 69 isOneCellInEditMode = true; 70 m_currentEditedCellIndex = index; 71 } 72 else { 73 if (isOneCellInEditMode) 74 { 75 isOneCellInEditMode = false; 76 m_table_view->closePersistentEditor(m_currentEditedCellIndex); 77 } 78 } 79 } 80 81 void AppRepoButtonDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, 82 const QModelIndex &index) const 83 { 84 int x, y, width, height; 85 x = option.rect.left() + option.rect.width() / 2 - 20; 86 y = option.rect.top() + 5; 87 width = 60; 88 height = 20; 89 editor->setGeometry(QRect(x, y, width, height)); 90 } 91 92 void AppRepoButtonDelegate::setText(const QString& text) 93 { 94 m_btnText = text; 95 } 96 97 void AppRepoButtonDelegate::setStyleSheet(const QString& qss) 98 { 99 m_btnQss = qss;100 }101 102 void AppRepoButtonDelegate::slotBtnClicked()103 {104 emit buttonClicked(m_currentEditedCellIndex);105 }
用法:
1 auto delegateBtn = new AppRepoButtonDelegate(ui->appTable);2 delegateBtn->setText(QStringLiteral("下载更新"));3 m_downloadUpdateDelegate = delegateBtn;4 connect(m_downloadUpdateDelegate, &AppRepoButtonDelegate::buttonClicked,5 this, &AppRepoPage::slotDownloadUpdateBtnClicked);6 ui->appTable->setItemDelegateForColumn(7 6, m_downloadUpdateDelegate); //给第6列添加下载更新按钮的委托
references: