1

我在 QSystemTrayIcon 中有一个 QMenu。两者都是 QMainWindow 对象的成员。

我希望 QSystemTrayIcon 的 QMenu 在右键单击(即,原因 QSystemTrayIcon::Context)和单击左键时(即,原因 QSystemTrayIcon::Trigger)完全相同。

默认情况下,右键单击行为就像我想要的那样。但是我不知道如何使左键单击与右键单击完全一样。到目前为止,我的努力使我:

 void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
 {
     if(reason==QSystemTrayIcon::Trigger)  trayIcon->contextMenu()->popup(QCursor::pos());
 }

但是,菜单在失去焦点时不会消失,而右键单击上下文菜单确实会在失去焦点时消失。

有没有办法让触发器像上下文一样?也许是一种抛出模拟信号或其他东西的方法?

4

2 回答 2

1

好吧,我需要做同样的事情,但无法弄清楚如何使用纯 Qt 代码干净地完成它,所以这里有一个适用于 Windows 的小技巧:

void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason)
    {
    case QSystemTrayIcon::Trigger:
    case QSystemTrayIcon::DoubleClick:
    case QSystemTrayIcon::MiddleClick:
        {
            POINT p;
            GetCursorPos(&p);
            HWND hwnd = WindowFromPoint(p);
            ScreenToClient(hwnd, &p);
            PostMessageA(hwnd, WM_RBUTTONDOWN, MK_RBUTTON, MAKELONG(p.x, p.y));
            PostMessageA(hwnd, WM_RBUTTONUP, 0, MAKELONG(p.x, p.y));
        }
        break;
    case QSystemTrayIcon::Context:
        show();
        setWindowState(windowState() & ~Qt::WindowMinimized | Qt::WindowActive);
        mTrayIcon->contextMenu()->popup(QCursor::pos());
        break;
    default:
        break;
    }
}
于 2013-10-17T19:22:07.663 回答
0

所以,如果我理解正确的话。

您让 Qt 处理正确的按钮(您没有在插槽中检查 Context ),然后菜单在失去焦点时消失。

但是您正在处理左键单击,并且您无法获得相同的行为。正确的?

我至少可以想到两种通过 eventFilter 执行此操作的方法:

这将是制造假事件的一种方式。

bool MainWindow::eventFilter(QObject *obj, QEvent *event){
if (event->type() == QEvent::MouseButtonPress) {
  QMouseEvent *mEvent = static_cast<QMouseEvent *>(event);
  if(mEvent->button() == Qt::LeftButton)
  {
    QMouseEvent my_event = new QMouseEvent ( mEvent->type(), 
        mEvent->pos(), Qt::Rightbutton , 
    mEvent->buttons(), mEvent->modifiers() );
     QCoreApplication::postEvent ( trayIcon, my_event );
    return true;
  }
} 
return QObject::eventFilter(obj, event);
}

安装

trayIcon->installEventFilter(this);

从主窗口

但是,我认为这有点棘手。

如果你正在制作一个 eventFilter,你可以在菜单上观察 focusOut 事件。

bool MainWindow::eventFilter(QObject *obj, QEvent *event){

  QMouseEvent *mEvent = dynamic_cast<QMouseEvent *>(event);
  if(mEvent)
  {
  if(mEvent->type() == QEvent::Leave || mEvent->type() == QEvent::WindowDeactivate)
  {
    trayIcon->contextMenu()->close();
    return true;
  }
} 
return QObject::eventFilter(obj, event);
}

请注意,我还没有尝试过。但应该值得一试。

一些方便的链接:

如何检测我的应用程序在 Qt 中失去焦点?

安装事件过滤器

事后

于 2013-05-08T17:42:57.640 回答