在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://stackoverflow.com/questions/43082419/create-pushbuttons-in-qtableview-with-qstyleditemdelegate-subclass/43109044#43109044

https://qtadventures.wordpress.com/2012/02/04/adding-button-to-qviewtable/

时间: 2024-08-03 11:29:11

在QTableView中某列中添加Button的导致滚动条滚动的时候消失的问题的相关文章

C# DataTable中返回列中的最大值

此处以表dt2中的keyIndex列(int类型)为例 1.通过linq来实现 int maxKeyIndex = dt2.AsEnumerable().Select(t => t.Field<int>("keyIndex")).Max(); Linq语法:点击打开链接2.通过Compute方法来实现 int ee = (int)dt2.Compute("Max(keyIndex)", "true"); Compute方法:点击

表单中输入内容,搜索时,下面table中该列中包含关键字的高亮显示

有时候为了在搜索时清楚直观,需要关键字的高亮显示, 效果如下: 思想:在下面table中,本来应该是直接渲染数据,此时,可以先写一个方法,里面包含两个参数,分别是该显示的内容以及进行搜索时输入的关键字,在该方法中,进行判断,若是该列内容中包含关键字,则将关键字颜色改变,然后替换掉:若是没有,则还是原样显示. 表单中: table表格中: 此时需要写关键字高亮显示的方法: 在该方法中,可以使用if判断来进行替换,也可以使用正则来写. 原文地址:https://www.cnblogs.com/520

在Where中对列使用函数,将导致其不可索引

在Sql语句的Select部分对字段编写标量函数是完全可以的,但是下面代码: select EmpNo,LastName from Emp where YEAR(HireDate)=2005 应当写为 select EmpNo,LastName from Emp where HireDate between '' and '' 如上所示重写这个语句后,DB2可以选择使用HireDate上的索引(如果存在这样一个索引).但是如果在使用了Year函数,DB2就无法使用该列的索引了. 虽然可以使用函数

SQL 中判断列中的值是否为null,为null时候用0来代替

string strsql = "select itemno,cname,ename,shortname,IntervalInvalid,IntervalCheck,IntervalInceptReceive,IntervalCheckSend,isnull(IntervalInvalid,0)+isnull(IntervalCheck,0)+isnull(IntervalCheckSend,0)+isnull(IntervalInceptReceive,0)as couns from test

Jquery Ajax 异步设置Table中某列的值

可根据table中某列中的ID去改变某列的值! JS: 1 $(document).ready(function () { 2 setTimeout(GetDate, 1000); 3 4 }); 5 6 function GetDate() { 7 $("#tbData tbody").find("tr").each(function () { 8 var prjectBalanceObj = $(this).find("td:eq(3)");

SqlSever基础 where _ 任意字符,查找一列中的内容的字符数为2的内容

镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ 1 code 1 --创建一个数据库 2 create database helloworld1 3 4 --用helloworld1这个数据库 5 use helloworld1 6 7 --创建一个表格teacher 8 create table Teacher 9 ( 10 Id int p

iOS 为自定义tableView添加button点击事件后获取其序号

在自定义tableView中,为cell添加button点击事件后,如何获取其对应的序号? 1.创建tableView: 先创建一个成员变量: @interface MyCameraViewController ()<UITableViewDelegate,UITableViewDataSource> { UITableView *_tableView; }@end 在viewDidLoad中初始化 _tableView = [[UITableView alloc] initWithFrame

Qt中的QTableView 中的列放入Widget

QTableView是Qt中Model View理念的框架,View只展现数据,所以通过互交修改编辑数据,需要用到委托这个概念Delegate. 所以基本思路是继承QItemDelegate这个类,然后overried里面的方法,然后通过QTableView的成员函数setItemDelegateForColumn就可以了. 以下代码是在某列中添加QComboBox: 1 ///////////////////////////EmployeePrivilegeComboxEditor.h////

以Table表为框架,在HTML中实现数据列的添加,删除,查找功能

在学习Javascript的过程中,首先遇到的便是对对象数据类型和对象函数的理解不够清晰透彻.这个需要的就只是多实践,写代码的时候仔细脑际每一个变量被赋予的数据类型和对象. 在这次实践中对该Table实现的功能有:隔行变色,列的添加和删除(子节点),鼠标移入移出变色事件,关键字查找,分类具体查找,关键字模糊查找,多关键字查找. 具体代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "