在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)
}
}
}
运行结果: