1

编辑和一些自我批评我尝试了两种给定的解决方案,它们都解决了我的问题,因此我感谢你们!我将透明解决方案标记为已接受,因为当我只有一个子小部件时,我认为这是最简单的实现,但我希望与其他初学者分享一些见解:

我第一次使用QLabel,默认情况下显然已启用Qt::WA_TransparentForMouseEvents,因此显然有效,但我也希望文本可以通过使用QPlainTextEdit来选择。可笑的是,这是不可能的,因为如果您尝试选择文本(通过单击),您将关闭窗口!我最终保持了透明度,而忽略了选择文本功能。


我猜我的以下问题之前已经在某个地方得到了回答,但是经过一个小时的搜索,我现在自己发布了这个问题。如果有人能指出一个已经回答的问题来解决我的问题,我将不胜感激。

无论如何,我正在使用 C++ 和 Qt 创建一个弹出窗口。我创建了以下PopupDialog类,它可以很好地用于所有目的。但是,我已经删除了它的框架(包括包含关闭按钮和窗口标题的栏)以使其看起来很简约,现在我希望它在用户在弹出窗口(对话框)内的任何位置按下/释放鼠标按钮时关闭.

下面的代码可以工作,但是我必须在 QDialog 窗口本身准确地单击并释放鼠标。如果鼠标悬停在显示文本的QDialog(例如 a )内的子小部件上,当我单击时它不会关闭。QPlainTextEdit

因此,我需要一个解决方案QDialog来识别QMouseEvents其子小部件。请不要犹豫,询问是否有不清楚的地方。我没有包含我的 mainwindow.h/.cpp 文件或popupdialog.ui文件,因为我认为在这里发布有点太多了,但.ui非常简单:只有一个QDialog窗口持有 a QBoxLayout,包含一个小部件, a 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();
    }
4

2 回答 2

2

正如您已经注意到的,鼠标事件是从子小部件处理的,如果不被接受,则会传播给父小部件。你可以在这里阅读更多关于它的信息

要在子小部件内完成单击时关闭弹出窗口,您可以做两件事。您可以尝试查看installEventFilter并将其设置在要调用的每个子小部件上close()

另一种选择需要你有一种 centralWidget (就像MainWindow通常有的那样) - 只是对你所有的子小部件进行分组。这样,您可以在其上调用setAttribute()来设置Qt::WA_TransparentForMouseEvents属性以简单地跳过处理小部件及其所有子级上的鼠标事件。

groupWidget->setAttribute(Qt::WA_TransparentForMouseEvents);

根据Qt文档:

启用后,此属性会禁用将鼠标事件传递给小部件及其子级。鼠标事件被传递给其他小部件,就好像小部件及其子级不存在于小部件层次结构中一样;鼠标点击和其他事件有效地“通过”它们。默认情况下禁用此属性。

这基本上意味着事件将向上传递到可以处理事件的第一个小部件。在您的情况下,它将是PopupDialog并且已经被覆盖的mouseReleaseEvent插槽。

于 2017-01-09T15:04:15.087 回答
1

在头文件中

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();
}
}
于 2017-01-09T15:03:38.327 回答