#python #python-3.x #pyqt #pyqt5
#python #python-3.x #pyqt #pyqt5
Вопрос:
Итак, у меня есть этот графический интерфейс, и я пытаюсь изменить его таблицу стилей всякий раз, когда установлен флажок. Вот упрощенная версия моего кода:
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
style_sheet = "#Form{background-color: rgb(255,255,255);}"
inverted_ss = "#Form{background-color: rgb(0,0,0);}"
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(698, 453)
Form.setStyleSheet(style_sheet)
#some design preferences here, including frame_19 and horizontalLayout_5 as seen below
self.checkBox = QtWidgets.QCheckBox(self.frame_19)
self.checkBox.setEnabled(True)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.checkBox.sizePolicy().hasHeightForWidth())
self.checkBox.setSizePolicy(sizePolicy)
self.checkBox.setMinimumSize(QtCore.QSize(29, 25))
self.checkBox.setMaximumSize(QtCore.QSize(29, 50))
self.checkBox.setBaseSize(QtCore.QSize(25, 25))
self.checkBox.setLayoutDirection(QtCore.Qt.LeftToRight)
self.checkBox.setAutoFillBackground(False)
self.checkBox.setText("")
self.checkBox.setIconSize(QtCore.QSize(21, 21))
self.checkBox.setCheckable(True)
self.checkBox.stateChanged.connect(self.mode_change)
self.checkBox.setTristate(False)
self.checkBox.setObjectName("checkBox")
self.horizontalLayout_5.addWidget(self.checkBox)
#some more design preferences here
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "App"))
def mode_change(self, state):
if state == QtCore.Qt.Checked:
Form.setStyleSheet(inverted)
else:
Form.setStyleSheet(style_sheet)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
Проблема в том, что он выдает мне предупреждение: «Неразрешенная ссылка: ‘Форма’ «. Есть идеи о том, как заставить это работать?
Комментарии:
1. Пожалуйста, покажите полную ошибку или предоставьте воспроизводимый код.
2. @MauriceMeyer Используемая мной среда разработки (PyCharm) отображает форму в виде предупреждения, в котором указано именно то, что я написал выше: «Неразрешенная ссылка: ‘Форма’ «. При запуске скрипта приложение открывается, но когда я нажимаю на флажок, оно выходит из строя и показывает сообщение «Процесс завершен с кодом выхода -1073740791 (0xC0000409)»
3. @MauriceMeyer код не воспроизводим, но проблема ясна: в
Form
областиmode_change()
нет ссылки на.
Ответ №1:
В вашем коде Form
используется только как локальная переменная, используемая в качестве аргумента как setupUi
, так и retranslateUi
функций. Поскольку в вашей mode_change
функции нет такого аргумента, python завершает работу, поскольку эта ссылка не существует в области действия функции.
Возможным решением было бы подключиться с использованием лямбда-выражения, которое также возвращает Form
экземпляр метода:
# ...
self.checkBox.stateChanged.connect(lambda state: self.mode_change(Form, state))
# ...
def mode_change(self, Form, state):
# ...
Кроме того, существует более концептуальная проблема с вашим кодом, и она заключается в том, что вы пытаетесь отредактировать файл, созданный с помощью pyuic
(или пытаетесь имитировать его поведение), чего никогда не следует делать. Чтобы правильно использовать эти файлы, вам нужно только импортировать их и использовать один из методов, предложенных в официальной документации о использовании конструктора.
Наиболее распространенным и простым методом является подход с множественным наследованием, для которого вы создаете подкласс как из класса widget , так и из класса pyuic. Чтобы использовать следующий код, создайте заново файл python с помощью pyuic
и назовите его ui_Form.py
.
from PyQt5 import QtWidgets
from ui_Form import Ui_Form
style_sheet = "#Form{background-color: rgb(255,255,255);}"
inverted_ss = "#Form{background-color: rgb(0,0,0);}"
class MyForm(QtWidgets.QWidget, Ui_Form):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.checkBox.stateChanged.connect(self.mode_change)
def mode_change(self, state):
if state == QtCore.Qt.Checked:
self.setStyleSheet(inverted)
else:
self.setStyleSheet(style_sheet)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
myForm = MyForm()
myForm.show()
sys.exit(app.exec_())
Комментарии:
1. Ваш ответ помог! Просто проблема, если у меня есть изображение в качестве фона в таблице стилей (например, ss = «#Form{background-image: path-to-image;}»), оно не будет отображаться. Должен ли я изменить #Form на что-то другое?
2. [После вашего редактирования] Оба варианта работают, я собираюсь использовать решение «лямбда-состояние», поскольку оно работает со всем, что я запрограммировал до сих пор. Большое вам спасибо, мне очень помогло
3. 1) как объясняется в ссылке на таблицу стилей , все пути должны использоваться с
url()
синтаксисом:background-image: url(path-to-image);
. 2) Я настоятельно рекомендую вам пересмотреть весь ваш проект и использовать предложенный метод, так как в конечном итоге у вас возникнет множество проблем как с сигнальными подключениями, так и всякий раз, когда вам потребуется изменить любой из созданных вами файлов пользовательского интерфейса; это займет некоторое время, но это единственный недостаток, поскольку все, что вы получите от этого, — это только множество преимуществ.4. 1) Я имею в виду, да, я знаю, как это должно быть, но это не работает. 2) В моем проекте около 32 классов форм, подобных приведенному в примере, просто может быть слишком поздно для изменений. И тот факт, что это работает так, это больше, чем я мог бы попросить. Спасибо за вашу помощь, я действительно ценю это!
5. Я знаю, что это должен быть другой вопрос, но есть ли какой-либо способ заставить это изменение таблицы стилей повлиять на несколько окон? (Например, если у меня открыто 3, чтобы повлиять на каждый из них)