之前在项目上需要在表格中加入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 #include <QStyledItemDelegate>
4 #include <QString>
5 #include <QPersistentModelIndex>
6
7 class QStyleOptionButton;
8 class CTableWidget;
9 class QPushButton;
10
11 class AppRepoButtonDelegate : public QStyledItemDelegate
12 {
13 Q_OBJECT
14
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 #include <QStyleOptionButton>
4 #include <QPainter>
5 #include <QApplication>
6 #include <QMouseEvent>
7 #include <QStandardItemModel>
8 #include <QPushButton>
9 #include <QTableView>
10
11 #include "CTableWidget.h"
12
13 AppRepoButtonDelegate::AppRepoButtonDelegate(QObject *parent)
14 : QStyledItemDelegate(parent)
15 {
16 CTableWidget *tabView = qobject_cast<CTableWidget*>(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:
https://stackoverflow.com/questions/12360111/qpushbutton-in-qtableview
https://stackoverflow.com/questions/25337740/how-to-add-qpushbutton-in-qtableview-when-loading-database-by-c
http://www.qtcentre.org/threads/32394-Add-QPushButton-to-cell-in-QTableView
https://forum.qt.io/topic/53467/how-to-add-qpushbutton-in-qtableview
https://stackoverflow.com/questions/43082419/create-pushbuttons-in-qtableview-with-qstyleditemdelegate-subclass/43109044#43109044
https://qtadventures.wordpress.com/2012/02/04/adding-button-to-qviewtable/