• 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);
  • 相关阅读:
    EXCRT
    棋盘组合数
    Luogu P3687 [ZJOI2017]仙人掌 题解
    P4727 [HNOI2009]图的同构记数 题解
    WC2019 T1 数树 题解
    生成函数学习笔记
    luogu P1275 魔板 题解
    多项式ln、牛顿迭代学习笔记
    白帽子讲web安全——白帽子兵法(设计安全方案中的技巧)
    白帽子讲web安全——一个安全解决方案的诞生细节
  • 原文地址:https://www.cnblogs.com/li-peng/p/4029885.html
Copyright © 2020-2023  润新知