背景
qt5.15.2自带的MenuItem设置图标,不生效(坑爹)
实现
main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import Qt.labs.platform 1.1
Window {
id: root
width: 640
height: 480
minimumWidth: 640
maximumWidth: 640
minimumHeight: 480
maximumHeight: 480
visible: true
title: qsTr("TrayDemo")
property var menuTray: null
flags: Qt.FramelessWindowsHint | Qt.Window | Qt.CustomizeWindowHint | Qt.WindowMinimizeButtonHint
SystemTrayIcon {
id: trayApp
icon.source: "qrc:/tray.ico"
visible: true
tooltip: "TrayMenu"
onActivated: {
if(SystemTrayIcon.Trigger == reason)
raiseWindow()
else if(SystemTrayIcon.Context == reason) {
if(null == menuTray) {
var component = Qt.createComponent("qrc:/TrayMenu.qml");
if(component.status == Component.Ready) {
menuTray = component.createObject(null)
}
}
var jsonPos = qmlHelper.getMousePos()
menuTray.x = jsonPos.x
menuTray.y = jsonPos.y - menuTray.height - 10
menuTray.showMenu()
}
}
}
function raiseWindow() {
root.visible = true
root.raise()
root.requestActivate()
}
}
TrayMenu.qml
import QtQuick.Window 2.15
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15
Window {
id: root
height: 125
width: 180
minimumWidth: 180
maximumWidth: 180
minimumHeight: 125
maximumHeight: 125
property int radiusWnd: 8
property int marginSpace: 5
property int marginWnd: 10
property int heightItem: 32
signal trayMenuClick(var nType)
enum TrayMenuType
{
ShowWindow,
About,
Exit
}
visible: false
color: "white"
//flags: Qt.FramelessWindowsHint | Qt.Tool | Qt.CustomizeWindowHint | Qt.WindowMinimizeButtonHint
flags: Qt.FramelessWindowsHint | Qt.Tool | Qt.CustomizeWindowHint | Qt.WindowMinimizeButtonHint
Rectangle{
id:base
z: 1
radius: root.radiusWnd
//antialiasing:true
anchors.fill: parent
clip: true
color: "transparent"
//color: "#00000000"
layer.enabled: true
layer.effect: OpacityMask
{
maskSource: Rectangle {
width: base.width
height: base.height
radius: base.radius
}
}
Rectangle{
radius: radiusWnd
anchors {
left: parent.left
leftMargin: 0
right: parent.right
rightMargin: 0
top: parent.top
bottom: parent.bottom
}
ListView {
id: viewContent
model: modelContent
delegate: delegateContent
clip: true
contentWidth: parent.width
anchors {
left: parent.left
leftMargin: 0
right: parent.right
rightMargin: 0
top: parent.top
topMargin: 0
bottom: parent.bottom
bottomMargin: marginWnd
}
}
// model for content
ListModel {
id: modelContent
}
// delegate for content
Component {
id: delegateContent
Rectangle {
width: root.width
height: heightItem
Image {
id: imgIcon
source: strIcon
width: 16
height: 16
anchors {
left: parent.left
leftMargin: 10
verticalCenter: parent.verticalCenter
}
}
Text {
id: textData
text: textMenu
anchors {
left: imgIcon.right
leftMargin: 5
right: parent.right
verticalCenter: parent.verticalCenter
}
color: "#3B3B3B"
font.pointSize: 8
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onEntered: {
parent.color = "lightblue"//"#F2F2F2"
}
onExited: {
parent.color = "white"
}
onClicked: {
trayMenuClick(type)
hideWindow()
}
}
}
}
}
}
Connections {
target: eventFilter
function onFocusOut() {
if(!root.visible) return
console.log("Focus out..")
var jsonPos = qmlHelper.getMousePos()
var x = jsonPos.x
var y =jsonPos.y
if((x < root.x || x > root.x + root.height)
|| (y < root.y || y > root.y + root.height)) {
//console.log("Hide window, x: " + x + ", rootX: " + root.x + ", y: " + y + ", rootY: " + root.y + ", visible: " + root.visible)
hideWindow()
}
}
}
function showMenu()
{
modelContent.clear()
modelContent.append({type: TrayMenu.ShowWindow, strIcon: "",textMenu: "显示主窗口"})
modelContent.append({type: TrayMenu.About, strIcon: "qrc:/tray.ico", textMenu: "关于"})
modelContent.append({type: TrayMenu.Exit, strIcon: "qrc:/tray.ico", textMenu: "退出"})
var currentFlags = root.flags
root.flags = currentFlags | Qt.WindowStaysOnTopHint
root.requestActivate()
root.show()
}
function hideWindow() {
var currentFlags = root.flags
root.flags = currentFlags & ~Qt.WindowStaysOnTopHint
root.visible = false
root.hide()
}
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "QmlHelper.h"
#include "CustomObject.h"
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QCoreApplication::setAttribute(Qt::AA_Use96Dpi);
QGuiApplication app(argc, argv);
app.installEventFilter(&EVENT_FILTER_INST);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("qmlHelper", &QML_CTRL_INST);
engine.rootContext()->setContextProperty("eventFilter", &EVENT_FILTER_INST);
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();
}
鼠标坐标获取
QVariant QmlHelper::getMousePos()
{
QPoint screen_pos = QCursor::pos();
QJsonObject jsonObj;
jsonObj.insert("x", screen_pos.x());
jsonObj.insert("y", screen_pos.y());
return jsonObj;
}
存在问题
1、无边框顶部会有点间距
2、弹出的菜单,首次无法点击外部关闭(需要点击主窗口或点击菜单);再次弹出就不会出现此问题