Я пытаюсь создать приложение с PyQT5 с использованием архитектуры MVC, и у меня возникают проблемы с пониманием того, как отправить часть информации из модели в представление. В приведенном ниже примере приложения в модели запущен таймер обратного отсчета, и я хочу, чтобы индикатор прогресса в представлении отслеживал его прогресс. Но я не уверен, как отправить информацию в представление из модели во время выполнения метода в модели. В моем случае, progress_bar обновляется только после завершения выполнения метода model.counter. Что было бы изящным способом справиться с этим? Мне нужно, чтобы прогресс_бара обновлялся по мере обновления файла model.i.
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()