Использование QDialog внутри MousePressEvent

У меня есть класс, который подклассы QDialog без переопределения exec(), accept() или reject() и еще один, который вызывает класс Dialog внутри его mousePaintEvent:

void Canvas::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton){
        if (dialog->isVisible()){
            dialog->setModal(true);
            dialog->move(QWidget::mapToGlobal(event->pos()));
             //I connect the dialog's accepted signal to the CallingClass's slot, that uses the information taken from the dialog
            connect(dialog, &Dialog::accepted, this, &CallingClass::slot);
            dialog->exec();
        }
    }
    if (dialog->isVisible()){
        if (dialog->rect().contains(event->pos())){
            dialog->reject();
        }
    }
}

Я пытался использовать существование диалога для проверки, но delete на самом деле не сработало (я поставил его после dialog.reject()), я даже пытался использовать логическое значение, которое я снова установил в false после dialog.reject( ) в последнем if, но я начинаю думать, что после .reject() ничего не работает. Как мне поступить?


person Ivan Bratoev    schedule 22.04.2015    source источник
comment
что вы на самом деле пытаетесь сделать на высоком уровне?   -  person UmNyobe    schedule 22.04.2015
comment
Это событие рисования Canvas (которое является QOpenGlWidget). Что я хочу сделать, так это открыть диалоговое окно при нажатии левой кнопки мыши, из которого я могу выбрать, что рисовать на холсте, и, пока диалоговое окно открыто, я хочу иметь возможность закрыть его, щелкнув за его пределами.   -  person Ivan Bratoev    schedule 23.04.2015


Ответы (2)


Насколько я понимаю, dialog->rect() не дает вам того, что вы хотите (см. это). К сожалению, я не могу протестировать его прямо сейчас, но я думаю, вам следует попробовать использовать его в сочетании с pos или попробуйте напрямую использовать frameGeometry. При этом у вас будет реальное положение и размер вашего окна относительно его родителя. Попробуйте увидеть значения, которые вы получаете как координаты из события щелчка, и значения из этих методов, чтобы выяснить, как именно их использовать... В основном вам нужно будет решить, использовать ли глобальные координаты для рабочего стола относительно вашего родительское окно.

person Ivaylo Petrov    schedule 23.04.2015
comment
Хотя это действительно помогает, я понимаю, что не задал вопрос должным образом. Речь идет о том, как мне проверить, присутствует ли диалоговое окно, в этом примере я проверяю isVisible(), до этого я пытался удалить диалоговое окно и проверить, является ли оно нулевым, я даже пробовал с логическим набором после dialog->reject( ) в конце, но ничего из этого не сработало, и я даже не уверен в причине - person Ivan Bratoev; 23.04.2015
comment
Поскольку щелчок по холсту внутри прямоугольника диалога невозможен, я сократил свой код до этого: -›isVisible()){ диалог-›setModal(false); диалог-›setVisible(true); } else { диалог-›setVisible(false); } } } Но почему-то isVisible всегда возвращает false (и отображается диалоговое окно). Почему? - person Ivan Bratoev; 23.04.2015
comment
dialog->isVisible() возвращает false сразу после того, как вы установили его в true? Я полагаю, что вы оставили стандартные реализации setVisible, isVisible, show и hide? - person Ivaylo Petrov; 23.04.2015
comment
Да, все провалилось, потому что что-то по иерархии оказалось не видно, хотя я это вижу. Я понял это правильно, поэтому я собираюсь опубликовать это как ответ. - person Ivan Bratoev; 23.04.2015
comment
Было бы интересно понять, почему, поскольку все предки видны, почему для параметра visible не установлено значение true? Жук? - person Ivan Bratoev; 23.04.2015

Проблема с isVisible, всегда возвращающим false, была связана с тем, что он возвращает true только в том случае, если все предки видны, как указано здесь: http://doc.qt.io/qt-5/qwidget.html#visible-prop Чего я не могу понять, так это почему некоторые из предков (класс является потомком дочерний элемент QWidget QTabWidget, добавленный из QDesigner), не будет помечен как видимый, так как он будет отображаться на экране. Я не получил isVisible, чтобы показать, действительно ли виден виджет (как он есть), но я применил обходной путь, используя классический логический подход:

void Class::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton){
        if (!dialogOpened){
            dialog->show();
            dialogOpened = true;
        } else {
            dialog->hide();
            dialogOpened = false;
        }
    }
}
person Ivan Bratoev    schedule 23.04.2015