qml调用C++创建右键菜单

在qml与QWidget混合编程的过程中,有时候qml创建的菜单不适用QWidget,这就时候就需要弹出QWidget自己的菜单,那么如何使用qml调用C++创建的菜单呢,下面看具体的示例:

#ifndef ACTIONITEMTYPE_H
#define ACTIONITEMTYPE_H

#include <QObject>

class ActionItemType: public QObject
{
    Q_GADGET
public:
    explicit ActionItemType(QObject *parent = nullptr);

    //操作类型
    enum ActionType
    {
        CopyAction = 1,             //复制
        DeleteAction = 2,           //删除
        PastedAction = 3,           //粘贴
    };
    Q_ENUM(ActionType)
};

#endif // ACTIONITEMTYPE_H
#include "actionitemtype.h"

ActionItemType::ActionItemType(QObject *parent)
    : QObject(parent)
{

}
#ifndef CUSTOMMENUITEM_H
#define CUSTOMMENUITEM_H

#include <QObject>

#include "actionitemtype.h"
#include <QMenu>
#include <QAction>


class CustomMenuItem: public QObject
{
    Q_OBJECT
public:
    static CustomMenuItem* instance();

    Q_INVOKABLE void createMenuAction(const QVariantList &actionTypeList);//添加多个右健菜单
    Q_INVOKABLE void addMenuAction(int actionType, QString strMenuName);//添加单个右健菜单
    Q_INVOKABLE void showMenu();//显示右健菜单

public:
    void initView();


public slots:
    void slotActionMenuCopy(bool checked);               //复制
    void slotActionMenuPaste(bool checked);              //粘贴
    void slotActionMenuDelete(bool checked);             //删除

    void slotAboutToHide();
    void slotAboutToShow();
    void slotHovered(QAction *action);
    void slotTriggered(QAction *action);
    //QWidget
    void slotCustomContextMenuRequested(const QPoint &pos);
    void slotWindowIconChanged(const QIcon &icon);
    void slotWindowTitleChanged(const QString &title);
    //QObject
    void slotDestroyed(QObject *obj);
    void slotObjectNameChanged(const QString &objectName);

signals:
    void signalCopyAction(const QString strName);


private:
    explicit CustomMenuItem(QObject *parent = nullptr);


private:
    QMenu   *m_pMenu;
    QAction *m_pCopyAction;             //复制
    QAction *m_pPasteAction;            //粘贴
    QAction *m_pDeleteAction;           //删除
    QString m_strName;                  //菜单操作名字
    int m_actionType;                   //菜单操作类型

};

#endif // CUSTOMMENUITEM_H
#include "custommenuitem.h"

#include <QFontMetrics>
#include <QTimer>
#include <QDebug>
#include <QList>

static CustomMenuItem* __customMenuItem = nullptr;


CustomMenuItem::CustomMenuItem(QObject *parent) : QObject(parent)
  ,m_pMenu(new QMenu())
  ,m_pCopyAction(new QAction(this))
  ,m_pPasteAction(new QAction(this))
  ,m_pDeleteAction(new QAction(this))
{

    initView();
}

CustomMenuItem *CustomMenuItem::instance()
{
    if(__customMenuItem == nullptr){
        __customMenuItem = new CustomMenuItem();
    }
    return __customMenuItem;
}

void CustomMenuItem::createMenuAction(const QVariantList &actionTypeList)
{

    qDebug() << "CustomMenuItem::crateRightMenuAction====actionTypeList.toStdList()===" << actionTypeList.toStdList() << " line==" << __LINE__;
    qDebug() << "CustomMenuItem::crateRightMenuAction====actionTypeList.count()===" << actionTypeList.count() << " line==" << __LINE__;
    m_pMenu->clear();
    for(int i = 0; i < actionTypeList.count(); ++i)
    {
        ActionItemType::ActionType actionType = (ActionItemType::ActionType)actionTypeList[i].toInt();
        switch (actionType)
        {
        case ActionItemType::ActionType::CopyAction :
        {
            m_pCopyAction->setText(QStringLiteral("复制"));
            connect(m_pCopyAction, &QAction::triggered, this, &CustomMenuItem::slotActionMenuCopy);
            m_pMenu->addAction(m_pCopyAction);
        }break;

        case ActionItemType::ActionType::PastedAction :
        {
            m_pPasteAction->setText(QStringLiteral("粘贴"));
            connect(m_pPasteAction, &QAction::triggered, this, &CustomMenuItem::slotActionMenuPaste);
            m_pMenu->addAction(m_pPasteAction);
        }break;

        case ActionItemType::ActionType::DeleteAction :
        {
            m_pDeleteAction->setText(QStringLiteral("删除"));
            connect(m_pDeleteAction, &QAction::triggered, this, &CustomMenuItem::slotActionMenuDelete);
            m_pMenu->addAction(m_pDeleteAction);
        }break;

        default:
            break;
        }
    }

    qDebug() << "CustomRightMenu::crateRightMenuAction===============1====";
    //菜单出现的位置为当前鼠标的位置
    m_pMenu->popup(QCursor::pos());
    qDebug() << "CustomRightMenu::crateRightMenuAction===============2====";

}

void CustomMenuItem::addMenuAction(int actionType, QString strMenuName)
{
    switch (actionType)
    {
    case ActionItemType::ActionType::CopyAction :
    {
        m_pCopyAction->setText(strMenuName);
        connect(m_pCopyAction, &QAction::triggered, this, &CustomMenuItem::slotActionMenuCopy);
        m_pMenu->addAction(m_pCopyAction);
    }break;

    case ActionItemType::ActionType::PastedAction :
    {
        m_pPasteAction->setText(strMenuName);
        connect(m_pPasteAction, &QAction::triggered, this, &CustomMenuItem::slotActionMenuPaste);
        m_pMenu->addAction(m_pPasteAction);
    }break;

    case ActionItemType::ActionType::DeleteAction :
    {
        m_pDeleteAction->setText(strMenuName);
        connect(m_pDeleteAction, &QAction::triggered, this, &CustomMenuItem::slotActionMenuDelete);
        m_pMenu->addAction(m_pDeleteAction);
    }break;

    default:
        break;
    }


}

void CustomMenuItem::showMenu()
{
    qDebug() << "CustomRightMenu::showRightMenu===============1====";
    //菜单出现的位置为当前鼠标的位置
    m_pMenu->popup(QCursor::pos());//这里要用popup,不能用exec否则多次调用切换页面时出存在资源释放的问题
    qDebug() << "CustomRightMenu::showRightMenu===============2====";
}

void CustomMenuItem::initView()
{
    //border-bottom:1px solid #FDCADB;/*为菜单项之间添加横线间隔*/
    m_pMenu->setStyleSheet("QMenu {background-color:rgb(253,253,254); border-style:solid; border-width:1px;border-color:#ffffff;border-radius:10px;}"
                           "QMenu::item {font-size:12px;color:rgb(0,0,0);padding-left:15px;background-color:rgb(255,255,255);border-bottom:1px solid #999999;}"
                           "QMenu::item:selected{font-size:12px;color:rgb(255,255,255);padding-left:15px;background-color:rgb(61,126,255);}");
    m_pMenu->setWindowFlags(Qt::CustomizeWindowHint);//隐藏标题栏
    m_pMenu->setWindowFlag(Qt::FramelessWindowHint);//去掉边框
    m_pMenu->setAttribute(Qt::WA_TranslucentBackground);//设置背景透明
    connect(m_pMenu, &QMenu::aboutToHide, this, &CustomMenuItem::slotAboutToHide);
    connect(m_pMenu, &QMenu::aboutToShow, this, &CustomMenuItem::slotAboutToShow);
    connect(m_pMenu, &QMenu::hovered, this, &CustomMenuItem::slotHovered);
    connect(m_pMenu, &QMenu::triggered, this, &CustomMenuItem::slotTriggered);
    connect(m_pMenu, &QMenu::customContextMenuRequested, this, &CustomMenuItem::slotCustomContextMenuRequested);
    connect(m_pMenu, &QMenu::windowIconChanged, this, &CustomMenuItem::slotWindowIconChanged);
    connect(m_pMenu, &QMenu::windowTitleChanged, this, &CustomMenuItem::slotWindowTitleChanged);
    connect(m_pMenu, &QMenu::destroyed, this, &CustomMenuItem::slotDestroyed);
    connect(m_pMenu, &QMenu::objectNameChanged, this, &CustomMenuItem::slotObjectNameChanged);
}

void CustomMenuItem::slotActionMenuCopy(bool checked)
{
    qDebug() << "CustomMenuItem::slotActionMenuCopy=====checked===" << checked << " line=" << __LINE__;
}
void CustomMenuItem::slotActionMenuPaste(bool checked)
{
    qDebug() << "CustomMenuItem::slotActionMenuPaste=====checked===" << checked << " line=" << __LINE__;
}

void CustomMenuItem::slotActionMenuDelete(bool checked)
{
    qDebug() << "CustomMenuItem::slotActionMenuDelete=====checked===" << checked << " line=" << __LINE__;
}
//=====================================================

void CustomMenuItem::slotAboutToHide()
{
    qDebug() << "CustomMenuItem::slotAboutToHide==== line=" << __LINE__;
}

void CustomMenuItem::slotAboutToShow()
{
    qDebug() << "CustomMenuItem::slotAboutToShow===== line=" << __LINE__;
}

void CustomMenuItem::slotHovered(QAction *action)
{
    qDebug() << "CustomMenuItem::slotHovered=====action===" << action << " line=" << __LINE__;
}

void CustomMenuItem::slotTriggered(QAction *action)
{
    qDebug() << "CustomMenuItem::slotTriggered=====action===" << action << " line=" << __LINE__;
}

void CustomMenuItem::slotCustomContextMenuRequested(const QPoint &pos)
{
    qDebug() << "CustomMenuItem::slotCustomContextMenuRequested=====pos===" << pos << " line=" << __LINE__;
}

void CustomMenuItem::slotWindowIconChanged(const QIcon &icon)
{
    qDebug() << "CustomMenuItem::slotWindowIconChanged=====icon===" << icon << " line=" << __LINE__;
}

void CustomMenuItem::slotWindowTitleChanged(const QString &title)
{
    qDebug() << "CustomMenuItem::slotWindowTitleChanged=====title===" << title << " line=" << __LINE__;
}

void CustomMenuItem::slotDestroyed(QObject *obj)
{
    qDebug() << "CustomMenuItem::slotDestroyed=====obj===" << obj << " line=" << __LINE__;
}

void CustomMenuItem::slotObjectNameChanged(const QString &objectName)
{
    qDebug() << "CustomMenuItem::slotObjectNameChanged=====objectName===" << objectName << " line=" << __LINE__;
}



#include <QGuiApplication>
#include <QApplication>
#include <QQmlApplicationEngine>
#include "actionitemtype.h"
#include "custommenuitem.h"
#include <QFont>

QObject *customMenuItem_instance(QQmlEngine *engine, QJSEngine *scriptEngine){
    Q_UNUSED(engine)
    Q_UNUSED(scriptEngine)
    return CustomMenuItem::instance();
}


int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    //QGuiApplication app(argc, argv);
    QApplication app(argc, argv);
    app.setOrganizationName("Hello World");
    app.setOrganizationDomain("https://www.hellowrold.com/");
    app.setApplicationName("Hello");
    app.setApplicationDisplayName(QStringLiteral("Hello"));


#if defined(Q_OS_WIN32)
    QFont font("Microsoft YaHei");
    app.setFont(font);
    //app.setWindowIcon(QIcon(":/images/hello_icon.ico"));
#elif defined(Q_OS_MACOS)
    QFont font("Segoe UI");
    app.setFont(font);
    app.setApplicationDisplayName(QStringLiteral("Hello"));
#endif

    Q_INIT_RESOURCE(qml);

    qmlRegisterUncreatableType<ActionItemType>("CustomMenu", 1, 0, "ActionType", "hello world");
    qmlRegisterSingletonType<CustomMenuItem>("CustomMenu", 1, 0, "CustomMenuItem", customMenuItem_instance);

    CustomMenuItem::instance();

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import CustomMenu 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    Button {
        text: qsTr("显示菜单")
        onClicked: {
            var menuItemArray = []
            menuItemArray.push(1)
            menuItemArray.push(2)
            menuItemArray.push(3)
            CustomMenuItem.createMenuAction(menuItemArray)

        }
    }
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值