我正在尝试使用MVC架构创建一个使用PyQT5的应用程序,但我在理解如何将一些信息从模型发送到视图时遇到了问题。在下面的示例应用程序中,我在模型中运行了一个倒计时计时器,我希望视图中的进度条可以跟踪它的进度。但是当模型中的方法正在执行时,我不确定如何将信息从模型发送到视图。在我的例子中,只有在完成model.counter方法的执行之后,才会更新progress_bar。什么是一个优雅的方式来处理这个问题?我需要在模型更新时更新progress_bar。
import sys
import time
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt5.QtWidgets import QGridLayout, QLineEdit, QPushButton, QVBoxLayout, QProgressBar
from PyQt5.QtCore import Qt
class ExampleGUI(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('Sample Application')
# Set some main window's properties
self.setFixedSize(235, 235)
# Set the central widget and the general layout
self.generalLayout = QVBoxLayout()
self._centralWidget = QWidget(self)
self.setCentralWidget(self._centralWidget)
self._centralWidget.setLayout(self.generalLayout)
# Create the display and the buttons
self._createDisplay()
self._createButtons()
def _createDisplay(self):
"""Create the display."""
# Create the display widget
self.display = QLineEdit()
self.progress_bar = QProgressBar()
# Set some display's properties
self.display.setFixedHeight(35)
self.display.setAlignment(Qt.AlignRight)
self.display.setReadOnly(True)
# Add the display to the general layout
self.generalLayout.addWidget(self.display)
self.generalLayout.addWidget(self.progress_bar)
def _createButtons(self):
"""Create the buttons."""
buttonsLayout = QGridLayout()
self.button1 = QPushButton("Start")
self.button1.setFixedSize(80, 40)
self.button2 = QPushButton("Clear")
self.button2.setFixedSize(80, 40)
buttonsLayout.addWidget(self.button1)
buttonsLayout.addWidget(self.button2)
self.generalLayout.addLayout(buttonsLayout)
def setDisplayText(self, text):
"""Set display's text."""
self.display.setText(text)
self.display.setFocus()
def clearDisplay(self):
"""Clear the display."""
self.setDisplayText("")
class Model:
def __init__(self):
self.counter = ''
self.i = ''
def countdown(self, counter):
self.i = 0
self.counter = counter
while self.i < self.counter:
self.i+=1
time.sleep(1)
return True
class Controller:
def __init__(self, view, model):
self._view = view
self._model = model
self._connect_settings_signals()
def _set_message(self):
self._view.progress_bar.setMaximum(10)
reply = self._model.countdown(10)
self._view.progress_bar.setValue(self._model.i)
if reply:
self._view.setDisplayText("Countdown complete!")
def _clear_message(self):
self._view.clearDisplay()
def _connect_settings_signals(self):
self._view.button1.clicked.connect(self._set_message)
self._view.button2.clicked.connect(self._clear_message)
def main():
"""Main function."""
# Create an instance of `QApplication`
pycalc = QApplication(sys.argv)
# Show the calculator's GUI
view = ExampleGUI()
view.show()
model = Model()
# Create instances of the model and the controller
ctrl = Controller(view=view, model=model)
# Execute calculator's main loop
sys.exit(pycalc.exec_())
if __name__ == "__main__":
main()发布于 2020-04-09 19:48:00
睡眠(1)是阻塞操作,事件循环仅在‘倒计时’完成后才返回'_set_message‘。我会将模型的更新和循环移出模型,返回到控制器。(作为一种控制,告诉模型更新它的值,请稍等片刻……)
我会更新一些类似的东西,比如:
def _set_message(self):
self._view.progress_bar.setMaximum(10)
self.i = 0
while self.i < 10:
self.i+=1
self._model.i += 1
self._view.progress_bar.setValue(self._model.i)
time.sleep(1)
self._view.setDisplayText("Countdown complete!")如果你坚持在模型中循环和睡眠(我不认为这是一个好主意),你将不得不深入到线程中,为该操作创建单独的线程,并保持主事件循环畅通,以便重新绘制进度条。(imho)
https://stackoverflow.com/questions/61120081
复制相似问题