Как распознать QMouseEvent внутри дочерних виджетов?


РЕДАКТИРОВАТЬ и Некоторая Самокритика
Я испробовал оба приведенных решения, которые оба решили мою проблему, и поэтому я благодарю вас обоих! Я пометил прозрачное решение как принятое, потому что я думал, что это самая простая реализация, когда у меня был только один дочерний виджет, но я хотел бы поделиться некоторыми соображениями с другими новичками:

Я впервые использовал QLabel, который в настоящее время включил Qt::WA_TransparentForMouseEvents по умолчанию и, таким образом, очевидно, работал, но я также хотел, чтобы текст можно было выбрать, используя QPlainTextEdit вместо. Смехотворно, это никак не возможно, потому что если вы попытаетесь выделить текст (нажав), вы закроете окно! В итоге я сохранил прозрачность и пренебрегал возможностью выбора текста.


Я предполагаю, что на мой следующий вопрос уже был дан ответ где-то раньше, но после часа поиска я теперь отправляю вопрос сам. Я благодарен, если кто-то может указать мне на уже отвеченный вопрос, который решает мою проблему.

Во всяком случае, я создаю всплывающее окно, используя C ++ и Qt. Я создал следующее PopupDialog класс, который работает хорошо и хорошо для всех своих целей. Однако я удалил его фрейм (включая панель, содержащую кнопку закрытия и заголовок окна), чтобы он выглядел минималистично, и теперь я хочу, чтобы он закрывался, если пользователь нажимает / отпускает кнопку мыши в любом месте всплывающего окна (диалоговое окно) ,

Приведенный ниже код работает, однако таким образом, что я должен щелкнуть и отпустить мышь точно в самом окне QDialog. Он не закроется, когда я нажму, если курсор мыши над дочерним виджетом (ами) внутри QDialogнапример, QPlainTextEdit, который отображает текст.

Следовательно, мне нужно решение для QDialog распознавать QMouseEvents внутри своих дочерних виджетов. Пожалуйста, не стесняйтесь спрашивать, если что-то неясно. Я не включил свои файлы mainwindow.h / .cpp или 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();
}

0

Решение

Как вы уже заметили, события мыши обрабатываются дочерними виджетами и передаются родителям, если они не принимаются. Вы можете прочитать больше об этом Вот

Чтобы закрыть всплывающее окно, когда щелчок сделан внутри дочернего виджета, вы можете сделать две вещи. Вы можете попробовать заглянуть в installEventFilter и настроить его на каждом дочернем виджете для вызова close(),

Другой вариант потребует от вас иметь вид CentralWidget (например, MainWindow обычно имеет) — просто сгруппировать все ваши дочерние виджеты. Таким образом, вы могли бы позвонить SetAttribute () на это установить Qt::WA_TransparentForMouseEvents свойство просто пропустить обработку событий мыши на виджете и всех его дочерних элементах.

groupWidget->setAttribute(Qt::WA_TransparentForMouseEvents);

В соответствии с Qt документы:

Если этот атрибут включен, он отключает доставку событий мыши
виджет и его дети. События мыши доставляются другим
виджеты, как будто виджет и его дочерние элементы не присутствовали в
иерархия виджетов; «щелчки мышью и другие события эффективно» проходят
через них. Этот атрибут по умолчанию отключен.

Что в основном означает, что событие будет передано по цепочке первому виджету, который может обработать событие. В вашем случае это будет PopupDialog и уже переопределено mouseReleaseEvent слот.

2

Другие решения

в заголовочном файле

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

в кпп

 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();
}
}
1

По вопросам рекламы [email protected]