在QTableView中某列中添加Button的导致滚动条滚动的时候消失的问题
Posted foo__hack
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在QTableView中某列中添加Button的导致滚动条滚动的时候消失的问题相关的知识,希望对你有一定的参考价值。
之前在项目上需要在表格中加入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://qtadventures.wordpress.com/2012/02/04/adding-button-to-qviewtable/
以上是关于在QTableView中某列中添加Button的导致滚动条滚动的时候消失的问题的主要内容,如果未能解决你的问题,请参考以下文章