V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Bssn
V2EX  ›  Qt

Qt5 托盘菜单右击时的异常

  •  
  •   Bssn · 1 天前 · 565 次点击

    程序运行在 macos, 如下图所示,当右击托盘图标时会发生异常(图中左上角),这是为什么呢? ChatClient-2025-03-25-18

    代码如下,还想请教一点,为什么单击的时候也会出现菜单呢?

    void MainWindow::SltTrayClicked(QSystemTrayIcon::ActivationReason reason)
    {
        switch (reason) {
        case QSystemTrayIcon::Trigger: // 单击
            if (!this->isVisible())
            {
                this->show();
            }
            break;
        case QSystemTrayIcon::Context: // 右击
            if (!m_trayMenu->isVisible())
            {
                m_trayMenu->show();
            }
            break;
        default:
            break;
        }
    }
    
    
    12 条回复    2025-03-26 11:02:43 +08:00
    NoOneNoBody
        1
    NoOneNoBody  
       1 天前
    trayMenu 要绑定 trayIcon ,没有绑定的话它只是个一般 menu
    Bssn
        2
    Bssn  
    OP
       1 天前
    @NoOneNoBody

    已经绑定了啊,请教一下:

    ``` c++

    void MainWindow::InitSystemTray()
    {
    // 1. 初始化托盘
    m_systemTray = new QSystemTrayIcon(this);
    m_systemTray->setIcon(QIcon(":/resource/background/app.png"));

    // 2. 初始化托盘菜单
    m_trayMenu = new QMenu(this);
    m_trayMenu->addAction("我在线上");
    m_trayMenu->addAction("离线");
    m_trayMenu->addSeparator();
    m_trayMenu->addAction("显示主面板");
    m_trayMenu->addSeparator();
    m_trayMenu->addAction("退出");

    // 3. 将托盘菜单添加进托盘
    m_systemTray->setContextMenu(m_trayMenu);
    m_systemTray->show();

    // 4. 关联菜单项对应的槽函数
    connect(m_systemTray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(SltTrayClicked(QSystemTrayIcon::ActivationReason)));
    connect(m_trayMenu, SIGNAL(triggered(QAction*)), this, SLOT(SltTrayMenuClicked(QAction*)));

    }

    ```
    NoOneNoBody
        3
    NoOneNoBody  
       1 天前
    我是写 pyqt ,C++只能约莫看懂
    看上去没太大问题,不过建议 trayicon/traymenu 创建时,parent 指定变量名,因为创建对象有多种方式,我写 pyqt 防止出错都写上 parent=xxx 的
    QSystemTrayIcon 可以是第一个变量 icon ,parent 默认用 null 创建的
    另一种是只用 parent ,但好像也要指定名字,当然 pyqt 这样写运行会直接报错,不知道 C++如何
    我习惯是继承并自定义类,限制了首个变量一定是 parent ,所以基本不会错
    Bssn
        4
    Bssn  
    OP
       1 天前
    @NoOneNoBody #3 好的,感谢回复,不过 pyqt 和 c++在创建对象时还是不太一样,可能由于 python 变量太灵活了。我发的那个代码应该没什么问题,但不知道为什么会出现第二个菜单,奇奇怪怪的 bug...
    NoOneNoBody
        5
    NoOneNoBody  
       1 天前
    @Bssn #4
    如果是两个菜单,那反而很明显,出现两个应该是创建时设了一个 parent ,后面又绑定了另一个
    应该创建菜单时不给 parent (无参数),反正后面会另外绑定
    NoOneNoBody
        6
    NoOneNoBody  
       1 天前
    @Bssn #4
    taskbar 在上面,看图没反应过来,只看到左上角的菜单,😅
    Bssn
        7
    Bssn  
    OP
       17 小时 57 分钟前
    @NoOneNoBody #5 试了一下,把 `m_trayMenu = new QMenu(this);` 改为 `m_trayMenu = new QMenu;` 右击时还是会有两个菜单,太奇怪了。。。
    Bssn
        8
    Bssn  
    OP
       17 小时 53 分钟前
    @NoOneNoBody #6 不好意思,我应该拿个红框标一下
    SamsonWang
        9
    SamsonWang  
       17 小时 45 分钟前
    `case QSystemTrayIcon::Context:`的时候啥都不用做,Qt 会自己把 context menu 显示出来
    Bssn
        10
    Bssn  
    OP
       17 小时 36 分钟前
    @SamsonWang 太厉害了,把这个 case 里面的东西删掉就真的只显示一个菜单了。不过还想请教个问题, `case QSystemTrayIcon::Trigger:` 按照这个 case 的逻辑, this 不是指向主面板吗?为什么单击的时候也会显示菜单呢?
    SamsonWang
        11
    SamsonWang  
       17 小时 26 分钟前
    QMenu 的 parent 是主面板,所以会随着主面板显示出来
    Bssn
        12
    Bssn  
    OP
       17 小时 15 分钟前
    @SamsonWang #11 懂了,感谢👍
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   981 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 20:18 · PVG 04:18 · LAX 13:18 · JFK 16:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.