如何防止成员QWidgets或QDialog对象从QMainWindow接管关键事件,一旦对话框被鼠标点击了?

问题描述:

所以我有一个用下面的代码描述QMainWindow类型的类:如何防止成员QWidgets或QDialog对象从QMainWindow接管关键事件,一旦对话框被鼠标点击了?

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

private: 
    void closeEvent(QCloseEvent *);\ 
    DimensionDialog *newResolution; 
    Ui::MainWindow *ui; 
    ImageInteraction *liveVideo; 
    ImageInteraction *modifiedVideo; 
    CameraControl *cameraControl; 
    QPushButton *pushToTalk; 
    QPushButton *audioSettingsSetup; 
    AudioSettings *audioSettings; 
    QPushButton *numberOfRunningThreads; 

protected: 
    void keyPressEvent(QKeyEvent * event); 
    void keyReleaseEvent(QKeyEvent * event); 

private slots: 
    void restartVideoWithNewResolution(int, int); 
}; 

从那里,你可以看到这个类并处理一些关键事件。

正如你所看到的,这个类也有成员DimensionDialogCameraControl,它们分别是QDialogQWigdet类型的类。现在,这两个成员也有自己的插槽,当按下某些按钮时会调用这些插槽。问题是当按下其中一个按钮时,相应的类(DimesionDialogCameraControl)将接管关键事件,并且MainWindow类无法捕获更多关键事件。

我不明白为什么会发生。我如何防止这种情况?我只希望通过MainWindow来处理关键事件。

谢谢。

+0

你玩过grabKeyboard吗? http://doc.qt.io/qt-4.8/qwidget.html#grabKeyboard – bibi

+0

谢谢,我不知道它。它在帮助。 –

+0

使用[installEventFilter](http://doc.qt.io/qt-4.8/qobject.html#installEventFilter)阻止对话接收此事件,然后分派到您的主窗口。 – Zen

如果要将关键事件传播给父项,则应该明确忽略它。

void DimensionDialog:keyPressEvent(QKeyEvent *event) 
{ 
    // ... 
    // do something then propagate event to parent 
    event->ignore(); 
} 

这是QEvent的行为。所以,对于鼠标事件,它也应该可以工作。

如果您需要在整个应用程序中全局检测关键事件,那么您可以在重新实现的QApplication :: notify()中捕获并处理它们(有关更多详细信息,请参阅Qt文档) 。

class KeyEventAwareApp : public QApplication 
{ 
    public: 
    using QApplication::QApplication; 

    bool notify(QObject* object,QEvent* event) 
    { 
     if(event->type() == QEvent::KeyPress) 
     { 
     // do any event processing here, for example redirect it to other object 
     // if swallow event then 
     return true; 
     // otherwise send event to the receiver 
     return object->event(event); 
     } 
     // we are interested only in key events, so forward the rest to receivers 
     return object->event(event); 
    } 
}; 
+0

试过,它不起作用。 grabKeyboard只是用MainWindow来控制键盘,但是当它们在MainWindow上打开时,这些键事件对其他小部件不起作用。 –

+0

我明白了。 DimensionDialog可能是顶层窗口而不是QMainWIndow的子窗口,事件传播将不起作用。然后,您需要在QApplication级别全局获取关键事件,然后将它们发送到主窗口中的某些方法进行处理。我将编辑帖子。 –