Qt UIC: немодальное всплывающее окно, не наследующее стиль от родителя

#pyqt5 #qt5 #uic

#pyqt5 #qt5 #МСЖД

Вопрос:

Я пытаюсь создать немодальное (немодальное) QMessageBox окно с несколькими кнопками и текстом. Чтобы сделать его немодальным, я даю ему MainWindow объект в качестве родителя (который наследуется от QMainWindow ).

Например:

 class MainWindow(QMainWindow):  ...   def create_popup(self):  message_box = QMessageBox(self)  # add buttons, text, etc.   message_box.setModal(False)  message_box.show()  

Однако возникает проблема, связанная с тем, что я предоставляю стиль своего главного окна через таблицу стилей, созданную из файла .ui (с использованием PyQt5.uic.loadUi('file', main_window) ). В файле .ui я указываю таблицу стилей главного окна как имеющую background-color: black . Поскольку QMessageBox я создаю наследует от MainWindow , он также наследует свою таблицу стилей, делая фон окна черным и фон кнопок. С наследованием, без модальности

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

Если я удаляю родителя QMessageBox (так я и делаю message_box = QMessageBox(None) ), вызов show() ничего не делает — я должен использовать exec_() . Однако это приводит к ожидаемому представлению коробки со стилем по умолчанию. Без наследования, модальный

Если я попытаюсь вручную переопределить атрибут цвета фона (с message_box.setStyleSheet("background-color: grey;") ), это испортит стиль кнопок и превратит их в прямоугольные поля (поскольку кнопки также наследуются от QMessageBox ). С пользовательской таблицей стилей

Я хотел бы сделать так, чтобы либо 1) стиль, применяемый к моему главному окну, не наследовался QMessageBox, 2) QMessageBox может быть немодальным, не будучи дочерним по отношению к главному окну, либо 3) Я могу переопределить стили с помощью полных стилей, которые используются по умолчанию для моей платформы (включая настройки операционной системы и темного режима, как это обычно делает Qt).

Комментарии:

1. Примечание. добавление self аргумента в виджет не имеет ничего общего с наследованием, которое относится к классу ; этот аргумент предназначен для объявления родительского значения объекта. Тем не менее, установка общего свойства для всего виджета, как правило, является плохой идеей, так как это свойство будет унаследовано всеми дочерними виджетами с неожиданными (и нежелательными) результатами: попробуйте добавить область прокрутки, и вы увидите. Пожалуйста, предоставьте полную таблицу стилей, которую вы используете для главного окна.

2. Таблица стилей MainWindow (от создателя Qt) такова background-color: rgb(0, 0, 0); . Как вы рекомендуете мне установить цвет фона без использования таблицы стилей?

3.Установка общих свойств таблиц стилей обычно не рекомендуется для объектов, у которых могут быть дочерние элементы (см. Комментарий выше). Есть возможность установить палитру приложения (или главного виджета): palette = self.palette() palette.setColor(palette.Window, Qt.black) self.setPalette(palette) (вы можете сделать то же самое в конструкторе, установив палитру виджета верхнего уровня). Но мне непонятно, как вы на самом деле хотите, чтобы отображалось ваше окно сообщения: должно ли оно наследовать фон главного окна? или он должен использовать стиль ОС по умолчанию?

4. Я хочу, чтобы он использовал стиль ОС по умолчанию, как если бы к нему вообще не применялся стиль (например, как он выглядит для модальной версии без родителей).

5. Возможной альтернативой может быть установка таблицы стилей только для центрального виджета (и его дочерних элементов); предполагая, что имя объекта Qt (заданное в конструкторе) центрального виджета centralwidget : #centralwidget, #centralwidget * { background: black; } (но, как уже говорилось, вы не должны использовать общие свойства для всех виджетов). Таким образом, диалоговое окно не унаследует таблицу стилей. Обратите внимание, что ваша попытка с show() не сработала, потому что вы не создаете постоянную ссылку для диалога, поэтому он мгновенно собирает мусор; измените на self.message_box = ... , и он будет работать.