在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头文件:
#pragma once #include <QStyledItemDelegate>
#include <QString>
#include <QPersistentModelIndex> class QStyleOptionButton;
class CTableWidget;
class QPushButton; class AppRepoButtonDelegate : public QStyledItemDelegate
{
Q_OBJECT public: explicit AppRepoButtonDelegate(QObject *parent = Q_NULLPTR);
~AppRepoButtonDelegate();
public:
void setText(const QString& text);
void setStyleSheet(const QString& qss); signals:
void buttonClicked(const QModelIndex& index);
public: QWidget* createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
private slots:
void cellEntered(const QModelIndex& index);
void slotBtnClicked();
private:
CTableWidget * m_table_view;
bool isOneCellInEditMode;
QPushButton* m_btn;
QPersistentModelIndex m_currentEditedCellIndex;
QString m_btnText;
QString m_btnQss;
};
Delegate类的CPP实现文件:
#include "AppRepoButtonDelegate.h" #include <QStyleOptionButton>
#include <QPainter>
#include <QApplication>
#include <QMouseEvent>
#include <QStandardItemModel>
#include <QPushButton>
#include <QTableView> #include "CTableWidget.h" AppRepoButtonDelegate::AppRepoButtonDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
CTableWidget *tabView = qobject_cast<CTableWidget*>(parent);
if (tabView)
{
m_table_view = tabView;
m_btn = new QPushButton(QStringLiteral(""), m_table_view);
m_btn->hide();
m_table_view->setMouseTracking(true);
connect(m_table_view, SIGNAL(entered(QModelIndex)),
this, SLOT(cellEntered(QModelIndex)));
isOneCellInEditMode = false;
}
} AppRepoButtonDelegate::~AppRepoButtonDelegate()
{
} void AppRepoButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
int x, y, width, height;
x = option.rect.left() + option.rect.width() / - ;
y = option.rect.top() + ;
width = ;
height = ; m_btn->setGeometry(QRect(x,y,width,height));
m_btn->setText(m_btnText);
m_btn->setStyleSheet(m_btnQss);
if (option.state == QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
QPixmap map = QPixmap::grabWidget(m_btn);
painter->drawPixmap(x, y, map);
} QWidget* AppRepoButtonDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QPushButton * btn = new QPushButton(parent);
connect(btn, &QPushButton::clicked, this, &AppRepoButtonDelegate::slotBtnClicked);
btn->setText(m_btnText);
btn->setStyleSheet(m_btnQss);
return btn;
} void AppRepoButtonDelegate::cellEntered(const QModelIndex& index)
{
if (index.column() == || index.column() == )
{
if (isOneCellInEditMode)
{
m_table_view->closePersistentEditor(m_currentEditedCellIndex);
}
m_table_view->openPersistentEditor(index);
isOneCellInEditMode = true;
m_currentEditedCellIndex = index;
}
else {
if (isOneCellInEditMode)
{
isOneCellInEditMode = false;
m_table_view->closePersistentEditor(m_currentEditedCellIndex);
}
}
} void AppRepoButtonDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
int x, y, width, height;
x = option.rect.left() + option.rect.width() / - ;
y = option.rect.top() + ;
width = ;
height = ;
editor->setGeometry(QRect(x, y, width, height));
} void AppRepoButtonDelegate::setText(const QString& text)
{
m_btnText = text;
} void AppRepoButtonDelegate::setStyleSheet(const QString& qss)
{
m_btnQss = qss;
} void AppRepoButtonDelegate::slotBtnClicked()
{
emit buttonClicked(m_currentEditedCellIndex);
}
用法:
auto delegateBtn = new AppRepoButtonDelegate(ui->appTable);
delegateBtn->setText(QStringLiteral("下载更新"));
m_downloadUpdateDelegate = delegateBtn;
connect(m_downloadUpdateDelegate, &AppRepoButtonDelegate::buttonClicked,
this, &AppRepoPage::slotDownloadUpdateBtnClicked);
ui->appTable->setItemDelegateForColumn(
, 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的导致滚动条滚动的时候消失的问题的更多相关文章
- Pandas中查看列中数据的种类及个数
Pandas中查看列中数据的种类及个数 读取数据 import pandas as pd import numpy as np filepath = 'your_file_path.csv' data ...
- excel中统计列中的值在其他列出现的次数多个条件
excel中统计列中的值在其他列出现的次数多个条件 =COUNTIFS(E2:E373,"=VIP经销商",J2:J373,K2) 解释 E列的第二行到第373行中值 等于 VIP ...
- python – 基于pandas中的列中的值从DataFrame中选择行
如何从基于pandas中某些列的值的DataFrame中选择行?在SQL中我将使用: select * from table where colume_name = some_value. 我试图看看 ...
- c# richTextBox1添加内容并将滚动条滚动到当前焦点处
1. StringBuilder sb = new StringBuilder(); StringBuilder的改变比string快多了 2. sb.Append("\r\n" ...
- 在Where中对列使用函数,将导致其不可索引
在Sql语句的Select部分对字段编写标量函数是完全可以的,但是下面代码: select EmpNo,LastName from Emp 应当写为 select EmpNo,LastName fro ...
- Jquery Ajax 异步设置Table中某列的值
可根据table中某列中的ID去改变某列的值! 只是参考,实际应用中不能这样做的,如果有很多行,频繁访问服务器,服务器是顶不住的! JS: $(document).ready(function () ...
- Qt中的QTableView 中的列放入Widget
QTableView是Qt中Model View理念的框架,View只展现数据,所以通过互交修改编辑数据,需要用到委托这个概念Delegate. 所以基本思路是继承QItemDelegate这个类,然 ...
- 在datagridview中添加button按钮
.Net的DataGridView控件中,提供了一种列的类型,叫 DataGridViewButtonColumn ,这种列类型是展示为一个 按钮,可以给button赋予相应的text,并且,此but ...
- javafx这些学会后,开发就不难了,往tablecloumn列中添加按钮,修改javafx中tableview中tablecell中的值,修改完回车表示保存到内存中
javafx开发过程中遇见难题,往tablecloumn列中添加按钮 想了很久的方法,也配有办法判断每行中有数据的地方添加按钮set bank_caozuo.setCellFactory((col)- ...
随机推荐
- Windows8.1 关机异常的解决
昨天电脑无法正常关机,关机后风扇仍然转,硬盘也在读写,等了很长时间都没有完全关机,只能强制关机.以前其他系统也遇到过这个问题,因此考虑还是驱动问题.回想了下之前装过VirtualBox,考虑到应该是V ...
- Cantor展开式
X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! 其中,a为整数,并且0<=ai<i(1<=i<=n).这就是康托展开 ...
- [leetcode]Candy @ Python
原题地址:https://oj.leetcode.com/problems/candy/ 题意: There are N children standing in a line. Each child ...
- 如何在Vblock里配置Boot from SAN
啥是vBlock ============ vBlock是VCE用在包含了它的数据中心产品的组件的机架上的一个商标名. 机架中的组件都是有VCE出厂前预先组装好的, 组件的预设以及解决方案, 都是客户 ...
- VS单元测试中Assert类的用法
首先说介绍一下,Assert类所在的命名空间为Microsoft.VisualStudio.TestTools.UnitTesting 在工程文件中只要引用Microsoft.VisualStudio ...
- CSS-文本垂直居中
文本水平居中可以将text-align设置为center即可,垂直居中的话如果是单纯的设置vertical-align是没办法单独设置成功的,垂直居中的文字分为单行文本和多行文本,主要是两种不同的实现 ...
- ofstream的使用方法--超级精细。C++文件写入、读出函数(转)
ofstream的使用方法ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间; 在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的, ...
- 个基于TensorFlow的简单故事生成案例:带你了解LSTM
https://medium.com/towards-data-science/lstm-by-example-using-tensorflow-feb0c1968537 在深度学习中,循环神经网络( ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十二)VMW安装四台CentOS,并实现本机与它们能交互,虚拟机内部实现可以上网。
Centos7出现异常:Failed to start LSB: Bring up/down networking. 按照<Kafka:ZK+Kafka+Spark Streaming集群环境搭 ...
- c#:对两个字符串大小比较(不使用c#/java内部的比较函数),按升序排序
题目:首先需要实现一个函数:两个字符串大小比较(不得使用c#/java系统函数)的自定义函数:之后对一个字符串数据进行按升序排序(在排序过程中使用字符串大小比较时,使用自定义的字符串大小比较函数). ...