Python PyQt5:连接到单击信号的插槽不工作
首先,对不起我的英语。我的母语是西班牙语。 所以,我正在做这个学习python的小项目。我正在学习如何使用PyQt5实现UI。这个应用程序很简单,它有三个输入、一个按钮和一个输出。 我在这个应用程序中使用MVC软件模式,我的视图、模型和控制器都在不同的文件中 问题是: 在控制器类中,我将唯一的按钮连接到一个名为(_calculate)的插槽。当我运行应用程序并按下该按钮时,终端应该打印一个文本,这样我就可以看到它是否工作了。终点站什么也看不见。 通过不同种类的研究,我发现如果我在视图类中执行相同的绑定,_calculate将被执行。我做了一个关于使用PyQt5的计算器的教程。教程中的计算器可以很好地使用MVC,所以我用它来判断我是否忘记或错过了什么,但没有明显的结果 我的控制器类Python PyQt5:连接到单击信号的插槽不工作,python,pyqt5,Python,Pyqt5,首先,对不起我的英语。我的母语是西班牙语。 所以,我正在做这个学习python的小项目。我正在学习如何使用PyQt5实现UI。这个应用程序很简单,它有三个输入、一个按钮和一个输出。 我在这个应用程序中使用MVC软件模式,我的视图、模型和控制器都在不同的文件中 问题是: 在控制器类中,我将唯一的按钮连接到一个名为(_calculate)的插槽。当我运行应用程序并按下该按钮时,终端应该打印一个文本,这样我就可以看到它是否工作了。终点站什么也看不见。 通过不同种类的研究,我发现如果我在视图类中执行相同
class Controller:
def __init__(self, view):
self._view = view
self._connectSignals()
def _connectSignals(self):
self._view.button.clicked.connect(self._calculate)
def _calculate(self):
print('trying to calculate')
我的观点课
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QHBoxLayout
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QLabel
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QSpacerItem
from PyQt5.QtWidgets import QSizePolicy
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import TextEdit
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt
from ToolController import Controller
class UserInterface(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('BDO Tool')
self.setFixedSize(450, 300)
self._centralWidget = QWidget(self)
self.setCentralWidget(self._centralWidget)
self._createWindowSkeleton()
def _createWindowSkeleton(self):
# Vertical container who contains all the program widget
self._generalLayout = QVBoxLayout()
self._centralWidget.setLayout(self._generalLayout)
self._generalLayout.setAlignment(Qt.AlignCenter)
self._generalLayout.addLayout(self._createFirstRow())
self._generalLayout.addLayout(self._createButton())
self._generalLayout.addWidget(self._createAreaText())
def _createFirstRow(self):
hLayout = QHBoxLayout()
spacer = QSpacerItem(20, 20, hPolicy=QSizePolicy.Expanding)
self._inputBoxes = {
self.INPUT_BASE_FAIL: (QPixmap(self.IMG_BASE_FAILS), QLineEdit()),
self.INPUT_TARGET_FAIL: (QPixmap(self.IMG_TARGET_FAIL), QLineEdit()),
self.INPUT_STACK_AMOUNT: (QPixmap(self.IMG_STACK_AMOUNT), QLineEdit()),
}
keys = list(self._inputBoxes.keys())
for key, value in self._inputBoxes.items():
pixmap, editLine = value
label = QLabel()
label.setPixmap(pixmap)
editLine.setFixedWidth(40)
editLine.setAlignment(Qt.AlignRight)
hLayout.addWidget(label)
hLayout.addWidget(editLine)
if key != keys[-1]:
hLayout.addSpacerItem(spacer)
return hLayout
def _createButton(self):
self.button = QPushButton('Calculate')
spacer = QSpacerItem(20, 20, hPolicy=QSizePolicy.Expanding)
hLayout = QHBoxLayout()
hLayout.addSpacerItem(spacer)
hLayout.addWidget(self.button)
hLayout.addSpacerItem(spacer)
return hLayout
def _createAreaText(self):
self._infoDisplay = QTextEdit()
self._infoDisplay.setEnabled(False)
return self._infoDisplay
INPUT_BASE_FAIL = 1
INPUT_TARGET_FAIL = 2
INPUT_STACK_AMOUNT = 3
IMG_BASE_FAILS = 'img\\user25x25.png'
IMG_TARGET_FAIL = 'img\\target25x25.png'
IMG_STACK_AMOUNT = 'img\\stack25x25.png'
我的主要
import sys
from PyQt5.QtWidgets import QApplication
from ToolView import UserInterface
from ToolController import Controller
def main():
app = QApplication(sys.argv)
view = UserInterface()
view.show()
Controller(view=view)
sys.exit(app.exec())
if __name__ == '__main__':
main()
问题是,您没有为控制器实例创建持久对象,因此该实例随后会立即被垃圾收集,因为它没有在其他任何地方被引用 只要实例引用存在,它就会按预期工作。
在这种情况下,局部变量就足够了,因为
app.exec()
将阻止main
中的进一步处理,从而确保实例将一直存在,直到它存在为止
def main():
app = QApplication(sys.argv)
view = UserInterface()
view.show()
controller = Controller(view=view)
sys.exit(app.exec())
尽管如此,我还是要告诉您,虽然从概念上讲使用MVC通常是一个好主意,但您应该谨慎地使用它,不要“夸大”模式,并且只有在它确实有助于开发的情况下
我想指出其中一个:
缺乏增量优势——UI应用程序已经被分解成组件,并通过组件体系结构实现代码重用和独立性,MVC没有任何增量优势
我知道你的例子是一个简单的概念性例子,但就它的作用而言,它肯定是一个过于复杂的例子。例如:
- 您似乎没有使用模型,或者至少您似乎不需要一个完整的MVC模式来实现这一点(只要这样做有实际优势,就应该选择MVC,而不是“因为您应该使用它”)李>
- 使用MVC模式并不一定意味着必须使用3个类(和3个单独的文件),这也可能会降低代码的可导航性;MVC主要是关于三个元素在程序逻辑中的划分方式:Qt(大多数提供UI元素的框架)已经在这方面有所帮助,因为它提供的UI元素除了显示自己几乎什么都不做,以及其他允许与它们交互的元素(文件访问、网络接口和实际模型)李>
- 过度使用函数来创建UI通常是一个坏主意,因为这会使事情变得比实际情况复杂得多,从可读性的角度来看,这一点最为重要:虽然使用单独的函数可能有助于保持代码“整洁”,但创建函数也是为了实现其可重用性,在您的
类中,有4个函数肯定只会使用一次UserInterface
\uuuu init\uuuu
中,它将自己设置为视图的成员,例如:self.\u view.Controller=self
。