[英]How to recognize QMouseEvent inside child widgets?
編輯和一些自我批評,我都嘗試了給定的解決方案,都解決了我的問題,因此我都謝謝你們! 我將透明解決方案標記為已接受,因為我認為當我只有一個子窗口小部件時,這是最簡單的實現,但是我希望與其他初學者分享一些見解:
我首先使用QLabel
,它默認情況下已啟用Qt::WA_TransparentForMouseEvents
,因此顯然可以正常工作,但我也希望通過使用QPlainTextEdit
來選擇文本。 可笑的是,這是不可能的,因為如果您嘗試選擇文本(單擊),則會關閉窗口! 最后,我保持了透明度,而忽略了選擇文本功能。
我猜我的以下問題已經在之前的某個地方得到了回答,但是經過一個小時的搜索,我現在將問題自己發布了。 如果有人能指出我已經解決了我的問題的問題,我將不勝感激。
無論如何,我正在使用C ++和Qt創建一個彈出窗口。 我創建了以下PopupDialog
類,該類可以很好地完成所有目的。 但是,我刪除了它的框架(包括包含關閉按鈕和窗口標題的欄)以使其看起來非常簡約,現在我希望如果用戶在彈出窗口(對話框)中的任何位置按下/釋放鼠標按鈕,則將其關閉。
下面的代碼有效,但是我必須在QDialog窗口本身上完全單擊並釋放鼠標。 如果我將鼠標懸停在QDialog
內部的子窗口小部件(例如,正在顯示文本的QPlainTextEdit
,則單擊它不會關閉。
因此,我需要QDialog
能夠識別其子窗口小部件內的QMouseEvents
的解決方案 。 請不要猶豫,問是否有不清楚的地方。 我沒有包含我的mainwindow.h / .cpp文件或popupdialog.ui
文件,因為我認為在這里popupdialog.ui
有點過多,但是.ui
極其簡單:僅QDialog
窗口保存一個QBoxLayout
,其中包含一個小部件QPlainTextEdit
。 如果有幫助,我可以應要求發布這些內容。
// popupdialog.h
#ifndef POPUPDIALOG_H
#define POPUPDIALOG_H
#include <QDialog>
#include <QString>
namespace Ui {class PopupDialog;}
class PopupDialog : public QDialog
{
Q_OBJECT
public:
explicit PopupDialog(QWidget *parent = 0, QString msgTxt="");
~PopupDialog();
private:
Ui::PopupDialog *ui;
QString messageText;
void mouseReleaseEvent(QMouseEvent*);
};
#endif //POPUPDIALOG_H
...
// popupdialog.cpp
#include "popupdialog.h"
#include "ui_popupdialog.h"
PopupDialog::PopupDialog(QWidget *parent, QString msgTxt) :
QDialog(parent),
ui(new Ui::PopupDialog),
messageText(msgTxt)
{
ui->setupUi(this);
setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
setModal(true);
ui->message_text_display->setText(messageText);
// The message_text_display is an instance of the class,
// "PlainTextEdit". Using "QLabel" partly solves my
// problem, but does not allow text selection.
}
PopupDialog::~PopupDialog()
{
delete ui;
}
void PopupDialog::mouseReleaseEvent(QMouseEvent *e)
{
this->close();
}
正如您已經注意到的,鼠標事件是從子窗口小部件處理的,如果不被接受,則會傳播給父母。 您可以在這里了解更多信息
要在子窗口小部件內單擊時關閉彈出窗口,您可以做兩件事。 您可以嘗試研究installEventFilter並將其設置在每個子小部件上,以調用close()
。
另一種選擇是要求您擁有一種centralWidget(就像MainWindow
通常具有的那樣)-只是將所有子小部件分組。 這樣,您可以在其上調用setAttribute()來設置Qt::WA_TransparentForMouseEvents
屬性,從而僅跳過處理小部件及其所有子級上的鼠標事件。
groupWidget->setAttribute(Qt::WA_TransparentForMouseEvents);
根據Qt
docs:
啟用后,此屬性將禁用向小部件及其子級傳遞鼠標事件。 鼠標事件會傳遞到其他窗口小部件,就像窗口小部件及其子級未出現在窗口小部件層次結構中一樣。 鼠標單擊和其他事件可以有效地“通過”它們。 默認情況下禁用此屬性。
基本上,這意味着該事件將沿着鏈傳遞到可以處理該事件的第一個小部件。 在您的情況下,它將是PopupDialog
和已經覆蓋的mouseReleaseEvent
插槽。
在頭文件中
class PopupDialog : public QDialog
{
Q_OBJECT
public:
explicit PopupDialog(QWidget *parent = 0, QString msgTxt="");
~PopupDialog();
//////////////////////////////////
protected:
bool eventFilter(QObject *obj, QEvent *event);
//////////////////////////////////////
private:
Ui::PopupDialog *ui;
QString messageText;
void mouseReleaseEvent(QMouseEvent*);
};
在cpp中
PopupDialog::PopupDialog(QWidget *parent, QString msgTxt) :
QDialog(parent),
ui(new Ui::PopupDialog),
messageText(msgTxt)
{
ui->setupUi(this);
setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
setModal(true);
ui->message_text_display->setText(messageText);
// The message_text_display is an instance of the class,
// "PlainTextEdit". Using "QLabel" partly solves my
// problem, but does not allow text selection.
///////////////////////////////////////
foreach (QObject *child, children())
{
child->installEventFilter(this);
}
///////////////////////////////////////
}
///////////////////////////////////////
bool PopupDialog::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::MouseButtonRelease)
{
this->close();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.