【问题标题】:PyQt - How can I re-initialise the whole code without restarting it?PyQt - 如何在不重新启动的情况下重新初始化整个代码?
【发布时间】:2018-04-21 00:48:43
【问题描述】:

我编写了一个由两个独立文件组成的 python GUI 程序;一个用于逻辑代码,另一个用于使用 PyQt4 的 GUI。某些对象(按钮、文本字段...)的行为在整个代码中发生了变化,我需要通过单击 QAction 类菜单项将所有内容重置为其原始状态。我该怎么做?

编辑:应该将 GUI 重置为原始状态的功能:

def newSession(self):
        self.ui.setupUi(self)
        self.filename = ""
        self.paramsSplitted = []
        self.timestep = None
        self.index = None
        self.selectedParam = None
        self.selectedMethod = None

        --Snip--

【问题讨论】:

  • 也许你可以看这里:stackoverflow.com/questions/4528347/…
  • @nanithehaddock:我检查了链接,但它讨论了删除小部件而不是重置它们。
  • 您是否使用 Qt Designer 来生成您的 GUI?如果你这样做了,你的 GUI 主类有方法self.setupUi。您可以将 QAcion 的信号triggered 连接到此方法。然后 GUI 将设置为初始状态。我没有检查 - 所以不能保证......
  • @Sven:是的,我使用了 Qt Designer,它有 self.seupUi 方法。我之前也尝试过你的建议,但问题是打开 QFileDialog 的按钮之一在通过函数再次调用它后什么也不做。我编辑了我的帖子并添加了有关程序的部分。有什么想法吗?
  • @gnome。您不应该在newSession 中调用setupUi,因为它会重新创建所有小部件、布局等并断开所有信号。 setupUi 应与所有信号连接和任何其他您只想在应用程序启动时执行一次 的初始化一起进入__init__。然后,newSession 方法应该只包含重置状态变量并将相关小部件恢复到其起始状态所需的任何内容。这个方法应该在__init__结束时调用,然后在需要重置gui的时候调用。

标签: python pyqt qaction


【解决方案1】:

你可以做什么:

  • 使用reset_everything 信号定义ResetHandler(QtCore.QObject) 对象
  • 在启动期间创建一个实例并将其设置在全局可用的QApplication 上,例如qapplication.reset_handler = ResetHandler()
  • 每个需要自我更新的 UI 元素都定义了一个 on_reset_everything_triggered() 槽。 (可选:例如,您也可以只使用update
  • 当您创建应该更新的 UI 元素时,请将它们连接到来自 QApplication 上的处理程序的全局可用的 reset_everything 信号。
  • 将您的QAction.triggeredResetHandler.reset_everything 信号连接。
  • 现在,每次按下 QAction 时,都会调用 reset_everything 信号,并且您连接的所有 UI 元素都会自行更新。

【讨论】:

  • 这是最简单的方法吗?我不太擅长 Python 编程,请您告诉我如何将这些步骤转换为代码行?
【解决方案2】:

正如您在评论中所要求的,这里是利用函数连接所有信号的示意方法和方法setupUi

class MainWindow(QtGui.QMainWindow) :
    def __init__(self) :
        QtGui.QMainWindow.__init__(self)
        self.ui.setupUi(self)

        # Some code

        self.connectAllSignals()

    def connectAllSignals(self) :
        self.someWidget.clicked.connect(self.someFunction)
        self.someAction.triggered.connect(self.otherFunction)

        # All the other signals

    def disconnectAllSignals(self) :
        try :
            self.someWidget.clicked.disconnect()
            self.someAction.triggered.disconnect()

            # All the other signals

        except :
            print("Something went wrong. Check your code.")
            pass

    def newSession(self) :
        self.ui.setupUi(self)
        self.disconnectAllSignals()
        self.connectAllSignals()

        # Do whatever it takes

这样可以确保您只有信号的初始设置,并且所有动态添加的连接都已断开。在disconnectAllSignals 方法中,确保所有小部件都存在并且所有信号在您调用它时至少有一个连接。如果您有动态调用的新小部件,您应该考虑在调用 connectAllSignals 后在方法 newSession 中删除它们。

【讨论】:

  • 不要打电话给setupUi()。这个函数的作用是创建小部件树。由于 PyQt 在下面有 Qt C++,这意味着每次创建新会话时您将分配越来越多的内存(只是为了确保在 Linux 或 Windows/MacOS 的替代方案上使用 Valgrind 进行测试)。即使这没有发生,并且您只是通过处理前一个小部件树来重新创建现有的小部件树,从性能的角度来看它仍然很差。
猜你喜欢
  • 1970-01-01
  • 2020-05-21
  • 2011-09-07
  • 1970-01-01
  • 2011-09-28
  • 2016-09-16
  • 1970-01-01
  • 1970-01-01
  • 2013-12-02
相关资源
最近更新 更多