Qt QHeaderView自绘实现表头双击编辑,和添加按钮

在做数据展示时,为了偷懒少布局些界面元素,结果后面发现某部分功能无法很容易的实现,然后想到了Qt提供了控件自绘功能。具体实现效果为:表头的双击弹出输入框改变表头名称,点击按钮退出应用,也可以自定义为QMenu菜单等显示方式(注:之前想到用委托结果,设置好委托后一直没有效果,最后查看文档发现这么一句 Note: Each header renders the data for each section itself, and does not rely on a delegate. As a result, calling a header's setItemDelegate() function will have no effect。因此知道每个头显示每个节本身的数据,并且不依赖于委托)

效果图:

头文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QHeaderView>

QT_BEGIN_NAMESPACE
class CustomHeaderView;
QT_END_NAMESPACE

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
    CustomHeaderView *m_pHeader;
};

class CustomHeaderView : public QHeaderView     //自定义Header
{
    Q_OBJECT

public:
    explicit CustomHeaderView(Qt::Orientation orientation, QWidget *parent = nullptr);
    ~CustomHeaderView() Q_DECL_OVERRIDE;

signals:
    void Sig_ButtonClicked();
    void Sig_SendEditMsg(QString);

protected:
    void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const Q_DECL_OVERRIDE;//自定义QHeaderView的展示
    void mousePressEvent(QMouseEvent*event) Q_DECL_OVERRIDE;
    void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE;

private:
    QIcon m_icon;
    QPushButton *m_pBtn;
    QLineEdit *m_pLineEdit;
};

#endif // WIDGET_H

源文件:

#include <QDebug>
#include <QPainter>
#include <QMouseEvent>
#include <QInputDialog>

#include "Widget.h"
#include "ui_Widget.h"

Widget::Widget(QWidget *parent) : QWidget(parent)
  , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QStringList headLabels;
    headLabels << "" << "";

    ui->treeWidget->setColumnCount(2);
    ui->treeWidget->setHeaderLabels(headLabels);

    m_pHeader = new CustomHeaderView(Qt::Horizontal,this);
    ui->treeWidget->setHeader(m_pHeader);
    connect(m_pHeader, &CustomHeaderView::Sig_SendEditMsg, [&](const QString &rMsg){
        ui->treeWidget->setHeaderLabel(rMsg);
    });

    connect(m_pHeader, &CustomHeaderView::Sig_ButtonClicked, qApp,&QApplication::quit);

    m_pHeader->setSectionResizeMode(1,QHeaderView::Fixed);
    m_pHeader->setSectionResizeMode(0,QHeaderView::Stretch);
}

Widget::~Widget()
{
    delete ui;
}

CustomHeaderView::CustomHeaderView(Qt::Orientation orientation, QWidget *parent):QHeaderView(orientation, parent)
{
    m_icon.addFile(":/button.png");
    m_pBtn = new QPushButton(this);
    m_pBtn->setFlat(true);
    connect(m_pBtn, &QPushButton::clicked, this, &CustomHeaderView::Sig_ButtonClicked);

    m_pLineEdit = new QLineEdit(this);
    m_pLineEdit->hide();



    setStretchLastSection(false);
}

CustomHeaderView::~CustomHeaderView()
{

}

void CustomHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
    painter->save();
    QHeaderView::paintSection(painter, rect, logicalIndex);
    painter->restore();

    m_pLineEdit->resize(rect.size());

    if(1 == logicalIndex)
    {
        QStyleOptionButton option;
        option.initFrom(this);
        option.rect = rect;
        option.icon = m_icon;
        option.iconSize = rect.size();
        option.features = QStyleOptionButton::Flat;

        style()->drawControl(QStyle::CE_PushButton, &option, painter, m_pBtn);
    }
}

void CustomHeaderView::mousePressEvent(QMouseEvent *event)
{
    if((event->button() == Qt::LeftButton) && 1 == logicalIndexAt(event->pos()))
    {
        emit Sig_ButtonClicked();
    }
}

void CustomHeaderView::mouseDoubleClickEvent(QMouseEvent *event)
{
    if((event->buttons() & Qt::LeftButton) && 0 == logicalIndexAt(event->pos()))
    {
        m_pLineEdit->show();
        m_pLineEdit->setFocus();

        m_pLineEdit->disconnect();      //注意:因为QLineEdit是根据焦点判断是否编辑结束的,所以这里要解决重复信号的问题
        connect(m_pLineEdit, &QLineEdit::editingFinished, this, [&]{
            QString strMsg = m_pLineEdit->text();
            emit Sig_SendEditMsg(strMsg);
            m_pLineEdit->disconnect();
            m_pLineEdit->hide();
            m_pLineEdit->clear();
        });
    }
}

猜你喜欢

转载自blog.csdn.net/biu__biu_biu/article/details/88778779
今日推荐