之前在项目上需要在表格中加入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() / - ;
  37. y = option.rect.top() + ;
  38. width = ;
  39. height = ;
  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() == || index.column() == )
  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() / - ;
  86. y = option.rect.top() + ;
  87. width = ;
  88. height = ;
  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. , 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/

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

  1. Pandas中查看列中数据的种类及个数

    Pandas中查看列中数据的种类及个数 读取数据 import pandas as pd import numpy as np filepath = 'your_file_path.csv' data ...

  2. excel中统计列中的值在其他列出现的次数多个条件

    excel中统计列中的值在其他列出现的次数多个条件 =COUNTIFS(E2:E373,"=VIP经销商",J2:J373,K2) 解释 E列的第二行到第373行中值 等于 VIP ...

  3. python – 基于pandas中的列中的值从DataFrame中选择行

    如何从基于pandas中某些列的值的DataFrame中选择行?在SQL中我将使用: select * from table where colume_name = some_value. 我试图看看 ...

  4. c# richTextBox1添加内容并将滚动条滚动到当前焦点处

    1.   StringBuilder sb = new StringBuilder(); StringBuilder的改变比string快多了 2. sb.Append("\r\n" ...

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

    在Sql语句的Select部分对字段编写标量函数是完全可以的,但是下面代码: select EmpNo,LastName from Emp 应当写为 select EmpNo,LastName fro ...

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

    可根据table中某列中的ID去改变某列的值! 只是参考,实际应用中不能这样做的,如果有很多行,频繁访问服务器,服务器是顶不住的! JS: $(document).ready(function () ...

  7. Qt中的QTableView 中的列放入Widget

    QTableView是Qt中Model View理念的框架,View只展现数据,所以通过互交修改编辑数据,需要用到委托这个概念Delegate. 所以基本思路是继承QItemDelegate这个类,然 ...

  8. 在datagridview中添加button按钮

    .Net的DataGridView控件中,提供了一种列的类型,叫 DataGridViewButtonColumn ,这种列类型是展示为一个 按钮,可以给button赋予相应的text,并且,此but ...

  9. javafx这些学会后,开发就不难了,往tablecloumn列中添加按钮,修改javafx中tableview中tablecell中的值,修改完回车表示保存到内存中

    javafx开发过程中遇见难题,往tablecloumn列中添加按钮 想了很久的方法,也配有办法判断每行中有数据的地方添加按钮set bank_caozuo.setCellFactory((col)- ...

随机推荐

  1. go语言之进阶篇借助bufio实现按行读取内容

    1.借助bufio实现按行读取内容 示例: package main import ( "bufio" "fmt" "io" "o ...

  2. [leetcode]Best Time to Buy and Sell Stock III @ Python

    原题地址:https://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/ 题意: Say you have an array ...

  3. 安装Lync 2013过程中遇到的第一个报错

    安装Lync 2013, 首先要去做的就是prepare AD Forest. 在使用向导的时候会遇到报错如下: Prepare Forest Active Directory setting exe ...

  4. C#窗体读取EXCEL存入SQL数据库

    windows窗体上放了一个Textbox1,2个按钮button1和button2~按button1选择excel文件~按button2进行相关处理 Code Snippet private  vo ...

  5. 【Java】PS-查看Java进程-线程数

    PS-查看Java进程-线程数 ps 线程 个数_百度搜索 查看进程的线程数命令 - CSDN博客 java命令行运行jar里的main类 - coderland - 博客园

  6. JAVA-SpringMVC开发第一个应用

    找到eclipse工具路径 打开eclipse.exe 选择workspace的存放位置,点击ok 点击file-new 选择web-dynamic web project(动态web项目)-next ...

  7. How to skip to next iteration in jQuery.each() util?

      [问] I'm trying to iterate through an array of elements. jQuery's documentation says: jquery.Each() ...

  8. JAVA Eclipse如何导入已有的项目

    File-Import,然后在弹出的窗口中输入exit,会自动提示下面的选项(已存在的项目)   把项目源代码放到Eclipse的工作目录,然后找到   导入完成    

  9. LintCode: Cosine Similarity

    C++ class Solution { public: /** * @param A: An integer array. * @param B: An integer array. * @retu ...

  10. 在Windows中监视IO性能

    附:在Windows中监视IO性能 本来准备写一篇windows中监视IO性能的,后来发现好像可写的内容不多,windows在细节这方面做的不是那么的好,不过那些基本信息还是有的. 在Windows中 ...