首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将信息从模型发送到视图、MVC架构、PyQT5

将信息从模型发送到视图、MVC架构、PyQT5
EN

Stack Overflow用户
提问于 2020-04-09 19:26:09
回答 1查看 79关注 0票数 0

我正在尝试使用MVC架构创建一个使用PyQT5的应用程序,但我在理解如何将一些信息从模型发送到视图时遇到了问题。在下面的示例应用程序中,我在模型中运行了一个倒计时计时器,我希望视图中的进度条可以跟踪它的进度。但是当模型中的方法正在执行时,我不确定如何将信息从模型发送到视图。在我的例子中,只有在完成model.counter方法的执行之后,才会更新progress_bar。什么是一个优雅的方式来处理这个问题?我需要在模型更新时更新progress_bar。

代码语言:javascript
复制
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()
EN

Stack Overflow用户

发布于 2020-04-09 19:48:00

睡眠(1)是阻塞操作,事件循环仅在‘倒计时’完成后才返回'_set_message‘。我会将模型的更新和循环移出模型,返回到控制器。(作为一种控制,告诉模型更新它的值,请稍等片刻……)

我会更新一些类似的东西,比如:

代码语言:javascript
复制
    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)

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61120081

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档