Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
QT:触发器上的上下文菜单_Qt_Event Handling_Focus_System Tray - Fatal编程技术网

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

QT:触发器上的上下文菜单,qt,event-handling,focus,system-tray,Qt,Event Handling,Focus,System Tray,我在QSystemTrayIcon中有一个QMenu。两者都是QMainWindow对象的成员 我希望在右键单击(即,原因QSystemTrayIcon::Context)和单次左键单击(即,原因QSystemTrayIcon::Trigger)时,QSystemTrayIcon的QMenu的行为完全相同 默认情况下,右键单击行为的行为与我所希望的一样。但是,我不知道如何使左键单击与右键单击完全相同。迄今为止,我的努力使我: void MainWindow::iconActivated(QSy

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

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

默认情况下,右键单击行为的行为与我所希望的一样。但是,我不知道如何使左键单击与右键单击完全相同。迄今为止,我的努力使我:

 void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
 {
     if(reason==QSystemTrayIcon::Trigger)  trayIcon->contextMenu()->popup(QCursor::pos());
 }
但是,菜单在失去焦点时不会消失,而右键单击打开上下文菜单会在失去焦点时消失


有没有办法让触发器像上下文一样工作?也许是一种发出模拟信号或其他什么的方式?

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

您让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);
}
从主窗口

但是,我认为这有点棘手

若你们正在制作一个事件过滤器,你们可以在菜单上观察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);
}
bool主窗口::事件过滤器(QObject*obj,QEvent*event){
QMouseEvent*mEvent=动态强制转换(事件);
if(mEvent)
{
如果(mEvent->type()==QEvent::Leave | | mEvent->type()==QEvent::WindowDeactivate)
{
trayIcon->contextMenu()->close();
返回true;
}
} 
返回QObject::eventFilter(对象,事件);
}
注意,我还没有试过。但应该值得一试

一些方便的链接:


如果我没弄错的话,那就这样吧

您让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);
}
从主窗口

但是,我认为这有点棘手

若你们正在制作一个事件过滤器,你们可以在菜单上观察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);
}
bool主窗口::事件过滤器(QObject*obj,QEvent*event){
QMouseEvent*mEvent=动态强制转换(事件);
if(mEvent)
{
如果(mEvent->type()==QEvent::Leave | | mEvent->type()==QEvent::WindowDeactivate)
{
trayIcon->contextMenu()->close();
返回true;
}
} 
返回QObject::eventFilter(对象,事件);
}
注意,我还没有试过。但应该值得一试

一些方便的链接:


我需要做同样的事情,但我不知道如何用纯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;
    }
}

我也需要做同样的事情,但我不知道如何用纯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;
    }
}

你的理解是正确的。在阅读您的示例时,由于某种原因,eventFilter在我的代码中没有被触发,看起来应该可以工作。对于menuAnd prolly中安装的第二个方法,也是第二个方法,它是QEvent::MouseMove。我将更改代码a实际上我还没有尝试第二种方法。我喜欢第一个,因为它使鼠标左键单击的行为完全像右键单击一样(这是我想要的),而不必经历并将每个行为分配给鼠标左键本身。我将尝试第二种方法,看看会发生什么。也许你必须做一些调整,使它工作。这只是证明你的理解是正确的。在阅读您的示例时,由于某种原因,eventFilter在我的代码中没有被触发,看起来应该可以工作。对于menuAnd prolly中安装的第二个方法,也是第二个方法,它是QEvent::MouseMove。我将更改代码a实际上我还没有尝试第二种方法。我喜欢第一个,因为它使鼠标左键单击的行为完全像右键单击一样(这是我想要的),而不必经历并将每个行为分配给鼠标左键本身。我将尝试第二种方法,看看会发生什么。也许你必须做一些调整,使它工作。这只是一个概念的证明