右击 QTreeWidgetItem,弹出选择菜单

该博客介绍了如何在Qt环境中创建一个包含自定义数据结构的QTreeWidget,并实现右键菜单功能。作者展示了如何定义一个userData_t结构体,将其注册到元类型系统,然后在QTreeWidgetItem中存储并检索这些数据。此外,还详细说明了如何响应右键点击事件,创建并显示上下文菜单,以及如何通过槽函数执行相关操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

先看效果:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTreeWidget>
#include <QMenu>
#include <QAction>
#include <QVBoxLayout>
#include <QDebug>



QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE


/* 注册自己的结构体 */
struct userData_t
{
    QString  sz_name;
    QString  sz_address;
    userData_t(QString n, QString addr);
    userData_t();
};
Q_DECLARE_METATYPE(userData_t);



class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    void  updateView(std::vector<userData_t> &showData);

private slots:
    //响应右击
    void  userClicked(QPoint pos);

private:
    Ui::MainWindow *ui;
    QTreeWidget *m_tree;

};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"


userData_t::userData_t(QString n, QString addr) : sz_name(n), sz_address(addr)
{
     qRegisterMetaType<userData_t>("userData_t");
}

userData_t::userData_t() : sz_name("NA"), sz_address("NA")
{
    qRegisterMetaType<userData_t>("userData_t");
}

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

    m_tree = new QTreeWidget();
    m_tree->setColumnCount(1);
    m_tree->setHeaderLabel("--demo---");
    m_tree->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(m_tree, &QTreeWidget::customContextMenuRequested,this,&MainWindow::userClicked);

    QVBoxLayout *lay = new QVBoxLayout();
    lay->addWidget(m_tree);
    lay->setMargin(0);
    lay->setSpacing(0);
    ui->groupBox->setLayout(lay);

#if 1
    //测试用做一个假数据
    std::vector<userData_t> tVec;
    tVec.push_back(userData_t("月读", "00110010"));
    tVec.push_back(userData_t("天照", "00110011"));
    tVec.push_back(userData_t("地爆天星", "00111010"));
    tVec.push_back(userData_t("神罗天征", "10111010"));
    tVec.push_back(userData_t("葵花宝典", "10111010"));
    updateView(tVec);
#endif
}

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


//////////////////////////// 响应右击 /////////////////////////////////
void MainWindow::userClicked(QPoint pos)
{
    QTreeWidgetItem* curItem= m_tree->itemAt(pos);
    if(curItem==NULL) return;

    QVariantMap varMap = curItem->data(0,Qt::UserRole).toMap();
    userData_t ret = varMap["DATA"].value<userData_t>(); //获取数据

    QAction *placeAct = new QAction("开始学习");
    connect(placeAct, &QAction::triggered, this, [&](){
        qDebug() << QString("【技能:%1】 ----  【 ID:%2】").arg(ret.sz_name).arg(ret.sz_address);
    });
    QAction *deleteAct = new QAction("下次再说");
    connect(deleteAct, &QAction::triggered, this, [&](){
        qDebug() << "算了";
    });

    QMenu menu(this);
    menu.addAction(placeAct);
    menu.addAction(deleteAct);
    menu.exec( m_tree->mapToGlobal(pos) );
}

//////////////////////////// 更新视图 /////////////////////////////////
void MainWindow::updateView(std::vector<userData_t> &showData)
{
    m_tree->clear();
    m_tree->setColumnCount(1);

    QTreeWidgetItem *firstTreeItem = new QTreeWidgetItem();
    m_tree->addTopLevelItem(firstTreeItem);
    firstTreeItem->setText(0, "0.0");
    firstTreeItem->setBackgroundColor(0, QColor::fromRgb(222,236,252));

    for (size_t i = 0; i < showData.size(); i++)
    {
        QTreeWidgetItem *blkChild = new QTreeWidgetItem();
        blkChild->setText(0, showData[i].sz_name);

        //设置userData
        QVariantMap data;
        data["DATA"] = QVariant::fromValue<userData_t>(showData[i]);
        blkChild->setData(0, Qt::UserRole, data);

        blkChild->setBackgroundColor(0, QColor::fromRgb(255,255,240));
        firstTreeItem->addChild(blkChild);
    }
    m_tree->expandAll();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何处惹尘埃~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值