QT:触发器上的上下文菜单



我有一个QMenu,在QSystemTrayIcon。它们都是QMainWindow对象的成员。

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

默认情况下右键点击的行为是我想要的。然而,我不知道如何使左键点击行为完全像右键点击。到目前为止,我的努力使我:

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

但是,当菜单失去焦点时它不会消失,而右键打开上下文菜单会使它在失去焦点时消失。

是否有办法使触发器的行为像上下文?也许是一种模拟信号之类的?

我需要做同样的事情,但不知道如何用纯Qt代码干净地完成它,所以这里有一个仅适用于windows的小hack:

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;
    }
}

如果我没理解错的话。

你让Qt处理右键(你不检查上下文在你的插槽),然后菜单消失时失去焦点。

但是你正在处理左键点击,你不能得到相同的行为。对吧?

我可以想到,至少,两种方法来做到这一点,通过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);

from Main Window

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

如果你正在创建一个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?

installEventFilter

postEvent

相关内容

  • 没有找到相关文章

最新更新