QTableView 一列添加两个按钮

在QTableView的一列里添加两个按钮,之前添加一个按钮的思路是一样的,只是计算了一下按钮的宽,放两个按钮而已。

添加一个按钮的例子:QTableView 添加按钮

本例源代码:QtTowButtons.rar

看一下列的效果

看一下添加两个按钮的效果点击第一个按钮弹出 but1 +当前列 点击第二个按钮弹出but2 + 当前行

下面是主要实现

继承自 QItemDelegate

主要是实现 了它的painter方法,把两个自定义的按钮绘制到视图并保存

还有editorEvent事件,用来处理点击事件,在点击时我们算一下鼠标的坐标在哪个按钮下,

再处理相应的点击事件

复制代码
#ifndef BUTTONDELEGATE_H
#define BUTTONDELEGATE_H

#include <QItemDelegate>

class ButtonDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    explicit ButtonDelegate(QObject *parent = 0);
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);

signals:

public slots:

private:
    void showMsg(QString str);

private:

    typedef QMap<QModelIndex, QPair<QStyleOptionButton*, QStyleOptionButton*>* >  collButtons;
    collButtons m_btns;

};

#endif // BUTTONDELEGATE_H
复制代码

按钮的具体实现

复制代码
#include "buttondelegate.h"

#include <QApplication>
#include <QMouseEvent>
#include <QMessageBox>
#include <QPainter>
#include <QStyleOption>
#include <QDesktopWidget>

ButtonDelegate::ButtonDelegate(QObject *parent) :
    QItemDelegate(parent)
{
}


void ButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QPair<QStyleOptionButton*, QStyleOptionButton*>* buttons = m_btns.value(index);
    if (!buttons) {
        QStyleOptionButton* button1 = new QStyleOptionButton();
        //button1->rect = option.rect.adjusted(4, 4, -(option.rect.width() / 2 + 4) , -4); //
        button1->text = "X";
        button1->state |= QStyle::State_Enabled;

        QStyleOptionButton* button2 = new QStyleOptionButton();
        //button2->rect = option.rect.adjusted(button1->rect.width() + 4, 4, -4, -4);
        button2->text = "Y";
        button2->state |= QStyle::State_Enabled;
        buttons =new  QPair<QStyleOptionButton*, QStyleOptionButton*>(button1, button2);
        (const_cast<ButtonDelegate *>(this))->m_btns.insert(index, buttons);
    }
    buttons->first->rect = option.rect.adjusted(4, 4, -(option.rect.width() / 2 + 4) , -4); //
    buttons->second->rect = option.rect.adjusted(buttons->first->rect.width() + 4, 4, -4, -4);
    painter->save();

    if (option.state & QStyle::State_Selected) {
        painter->fillRect(option.rect, option.palette.highlight());

    }
    painter->restore();
    QApplication::style()->drawControl(QStyle::CE_PushButton, buttons->first, painter);
    QApplication::style()->drawControl(QStyle::CE_PushButton, buttons->second, painter);
}

bool ButtonDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    if (event->type() == QEvent::MouseButtonPress) {

        QMouseEvent* e =(QMouseEvent*)event;

        if (m_btns.contains(index)) {
            QPair<QStyleOptionButton*, QStyleOptionButton*>* btns = m_btns.value(index);
            if (btns->first->rect.contains(e->x(), e->y())) {
                btns->first->state |= QStyle::State_Sunken;
            }
            else if(btns->second->rect.contains(e->x(), e->y())) {
                btns->second->state |= QStyle::State_Sunken;
            }
        }
    }
    if (event->type() == QEvent::MouseButtonRelease) {
        QMouseEvent* e =(QMouseEvent*)event;

        if (m_btns.contains(index)) {
            QPair<QStyleOptionButton*, QStyleOptionButton*>* btns = m_btns.value(index);
            if (btns->first->rect.contains(e->x(), e->y())) {
                btns->first->state &= (~QStyle::State_Sunken);
                showMsg(tr("btn1 column %1").arg(index.column()));
            } else if(btns->second->rect.contains(e->x(), e->y())) {
                btns->second->state &= (~QStyle::State_Sunken);
                showMsg(tr("btn2 row %1").arg(index.row()));
            }
        }
    }
}

void ButtonDelegate::showMsg(QString str)
{
    QMessageBox msg;
    msg.setText(str);
    msg.exec();
}
复制代码

好了自定义按钮处理完了

我们建一个Table添加一些数据

复制代码
#ifndef TABLEMODEL_H
#define TABLEMODEL_H

#include <QAbstractTableModel>

class TableModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    explicit TableModel(QObject *parent = 0);
    int rowCount(const QModelIndex &parent) const;
    int columnCount(const QModelIndex &parent) const;
    QVariant data(const QModelIndex &index, int role) const;
    Qt::ItemFlags flags(const QModelIndex &index) const;
    void setHorizontalHeader(const QStringList& headers);
    QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    void setData(const QVector<QStringList>& data);
    QVector<QStringList>& DataVector() {return m_data;}
    ~TableModel(void);

signals:

public slots:


private:
    QStringList m_HorizontalHeader;
    QVector<QStringList> m_data;
};

#endif // TABLEMODEL_H
复制代码

model的实现 并添加一些数据

复制代码
#include "tablemodel.h"

TableModel::TableModel(QObject *parent) :
    QAbstractTableModel(parent)
{
}

TableModel::~TableModel()
{

}


int TableModel::rowCount(const QModelIndex &parent) const
{
    return m_data.size();
}

int TableModel::columnCount(const QModelIndex &parent) const
{
    return m_HorizontalHeader.count();
}

QVariant TableModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();
    if (role == Qt::DisplayRole) {
        int ncol = index.column();
        int nrow =  index.row();
        QStringList values = m_data.at(nrow);
        if (values.size() > ncol)
            return values.at(ncol);
        else
        return QVariant();
    }
    return QVariant();
}

Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::NoItemFlags;

    Qt::ItemFlags flag = QAbstractItemModel::flags(index);

    // flag|=Qt::ItemIsEditable // 设置单元格可编辑,此处注释,单元格无法被编辑
    return flag;
}

void TableModel::setHorizontalHeader(const QStringList &headers)
{
    m_HorizontalHeader =  headers;
}


QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
        return m_HorizontalHeader.at(section);
    }
    return QAbstractTableModel::headerData(section, orientation, role);
}

void TableModel::setData(const QVector<QStringList> &data)
{
    m_data = data;
}
复制代码

TableView的实现,和model关联

复制代码
#ifndef TABLEVIEW_H
#define TABLEVIEW_H

#include <QTableView>
#include "tablemodel.h"
#include "buttondelegate.h"

class TableView : public QTableView
{
    Q_OBJECT
public:
    explicit TableView(QWidget *parent = 0);
    TableModel* tableModel() {return m_model;}

    ~TableView();

signals:

public slots:

private:
    void iniData();

private:
    TableModel *m_model;
    ButtonDelegate *m_buttonDelegate;

};

#endif // TABLEVIEW_H
复制代码
复制代码
#include "tableview.h"

#include "tablemodel.h"
#include "buttondelegate.h"

TableView::TableView(QWidget *parent) :
    QTableView(parent)
{
    iniData();
}

TableView::~TableView()
{
    delete m_model;
}

void TableView::iniData()
{
    m_model = new TableModel();
    this->setModel(m_model);
    QStringList headers;
    headers << "Id" << "Progress";
    m_model->setHorizontalHeader(headers);

    QVector<QStringList> data;
    data.append(QStringList() << "1" << "22");
    data.append(QStringList() << "2" << "32");
    data.append(QStringList() << "3" << "2");
    data.append(QStringList() << "4" << "80");
    data.append(QStringList() << "5" << "40");
    m_model->setData(data);

    m_buttonDelegate = new ButtonDelegate(this);
    this->setItemDelegateForColumn(1, m_buttonDelegate);
    emit m_model->layoutChanged();
    this->setColumnWidth(1, 500);
}
复制代码

这就完成了

我们看一下调用

    this->resize(800, 600);
    TableView *tv = new TableView(this);
    QVBoxLayout* layout = new QVBoxLayout();

    layout->addWidget(tv);
    this->setLayout(layout);

 

本文转自lpxxn博客园博客,原文链接:http://www.cnblogs.com/li-peng/p/4029885.html,如需转载请自行联系原作者

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QTableView添加表头按钮,可以通过自定义表头视图来实现。步骤如下: 1. 继承QHeaderView类,创建自定义的表头视图类(例如MyHeaderView)。 2. 在自定义的表头视图类中重写paintSection()函数,用于绘制表头的每个部分。 3. 在paintSection()函数中判断绘制的是哪个部分,如果是最后一列,就绘制一个按钮。 4. 在重写的paintSection()函数中,监听鼠标点击事件,当点击按钮时,发射一个信号。 5. 在使用QTableView的地方,使用自定义的表头视图类作为表头视图。 6. 在控制QTableView的类中,连接自定义表头视图的信号到槽函数,实现按钮的功能。 以下是一个简单的例子来说明: ```python from PyQt5.QtWidgets import QTableView, QApplication, QMainWindow, QHeaderView, QWidget, QVBoxLayout, QPushButton from PyQt5.QtCore import Qt, QAbstractTableModel, QModelIndex from PyQt5.QtGui import QPainter class MyHeaderView(QHeaderView): def paintSection(self, painter, rect, logicalIndex): # 绘制表头的每个部分 painter.save() painter.drawText(rect, Qt.AlignCenter, self.model().headerData(logicalIndex, Qt.Horizontal)) painter.restore() # 如果是最后一列,绘制一个按钮 if logicalIndex == self.model().columnCount() - 1: painter.save() buttonRect = rect.adjusted(10, 5, -10, -5) painter.drawRoundedRect(buttonRect, 5, 5) painter.drawText(buttonRect, Qt.AlignCenter, "按钮") painter.restore() def mousePressEvent(self, event): # 监听鼠标点击事件 for logicalIndex in range(self.model().columnCount()): rect = self.sectionRect(logicalIndex) if rect.contains(event.pos()): if logicalIndex == self.model().columnCount() - 1: # 点击了最后一列按钮 self.sectionClicked.emit(logicalIndex) return super().mousePressEvent(event) class MyTableModel(QAbstractTableModel): def __init__(self): super().__init__() self.data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] def rowCount(self, parent=QModelIndex()): return len(self.data) def columnCount(self, parent=QModelIndex()): return len(self.data[0]) def data(self, index, role=Qt.DisplayRole): if role == Qt.DisplayRole: return str(self.data[index.row()][index.column()]) return None def headerData(self, section, orientation, role=Qt.DisplayRole): if role == Qt.DisplayRole: if orientation == Qt.Horizontal: return f"列{section}" if orientation == Qt.Vertical: return f"行{section+1}" return None class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("QTableView表头添加按钮") self.resize(300, 200) self.tableView = QTableView() self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 设置自定义的表头视图 headerView = MyHeaderView(Qt.Horizontal, self.tableView) self.tableView.setHorizontalHeader(headerView) # 连接自定义表头视图的信号到槽函数 headerView.sectionClicked.connect(self.onHeaderButtonClicked) # 设置数据模型 model = MyTableModel() self.tableView.setModel(model) self.setCentralWidget(self.tableView) def onHeaderButtonClicked(self, logicalIndex): print(f"点击了第{logicalIndex+1}列的按钮") if __name__ == "__main__": import sys app = QApplication(sys.argv) mainWindow = MainWindow() mainWindow.show() sys.exit(app.exec_()) ``` 以上是一个简单的示例,实现了在QTableView的表头中添加了一个按钮。点击按钮时,会打印出对应的列号。根据自己的需要,可以进一步定制按钮的外观和功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值