zoukankan      html  css  js  c++  java
  • 在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/

  • 相关阅读:
    Spring MVC与JAX-RS比较与分析
    JDK历史版本下载
    第六篇:为多态基类声明虚析构函数
    第五篇:明确拒绝不想编译器自动生成的拷贝构造函数和赋值运算符重载函数
    第四篇:了解 C++ 默默编写并调用的函数
    第三篇:确保对象在被使用前的初始化
    poj 2125(最小割)
    hdu 4704(费马小定理)
    hdu 4705(树形DP)
    poj 3469(网络流模版)
  • 原文地址:https://www.cnblogs.com/foohack/p/8108446.html
Copyright © 2011-2022 走看看