在 Pyside 中执行函数期间等待按钮单击

Posted

技术标签:

【中文标题】在 Pyside 中执行函数期间等待按钮单击【英文标题】:Waiting for a button click during the execution of a function in Pyside 【发布时间】:2014-05-25 19:30:03 【问题描述】:

我有多个按钮。当我单击其中一个时,我调用了一个迭代表行的函数(例如,更改行的背景颜色)。在这个函数的执行过程中,在迭代的中间,我想“暂停”并等待另一个按钮被点击,以便恢复函数的执行。在此“暂停”期间,我希望禁用或忽略所有其他按钮(即我等待被点击的按钮)。

我研究了 QTimer 和 QThread,但我认为我不必要地过度复杂化了事情。正在寻找建议...

【问题讨论】:

【参考方案1】:

首先,您需要在迭代结束或开始时调用QtGui.qApp.processEvents() 方法,以便在循环执行期间使 gui 响应。然后你需要维护一个list的行(比如self.allRows),在每次迭代中从list弹出一行更改背景颜色并将其附加到第二个list(比如self.doneRows) .还要在__init__ 中声明一个布尔变量为False(比如self.pause = False),并在循环的开头添加一个检查语句,如果self.pauseTruebreak 循环。然后你需要添加一个槽来将self.pause的值更新为True。

def pause_execution(self):
    self.pause = True
    # loop through all the buttons to make them disabled excluding the pause and resume buttons
    for btn in self.buttons:
        btn.setEnabled(False)
    QtGui.qApp.processEvents()

Pause 按钮的点击信号连接到此插槽。现在循环将被打破,self.allRows 仅包含尚未更改背景颜色的行。创建另一个插槽以再次恢复循环。这次循环将只改变剩余行的背景颜色。

def resume(self):
    self.stop = False
    # loop through all the buttons that were disabled, to make them enabled (if you need to)
    for btn in self.buttons:
        btn.setEnabled(True)
    QtGui.qApp.processEvents()
    # call the method which contains the background color changing loop.

【讨论】:

【参考方案2】:

我认为您正在寻找 for this 根据鼠标按钮单击来执行每个方法:

myWidget.setDisabled(true)

然后,您可以找到主窗口的所有子窗口或根窗口小部件,this way:

widgets = form.findChildren(QtGui.QWidget)

然后,您可以将按钮单击连接到所需的方法,如下所示:

button.clicked.connect(setDisableWidgets)

所以,这是一个简单的例子:

import sys
from PySide.QtCore import *
from PySide.QtGui import *

g_disable = true
g_mainWidget = ...

def setDisableWidgets():
    ''' This will get more exciting when you have other widgets, too,  for sure '''
    widgets = mainWidget.findChildren(QtGui.QWidget)

    for widget in widgets:
        # filter out push button though based objectName for instance
        widget.setDisabled(disable)

    # Toggle for the next run
    disable = not disable

app = QApplication(sys.argv)
button = QPushButton("Click me")
button.clicked.connect(setDisableWidgets)
button.show()
app.exec_()

在您的 QThread 运行中,您可以扩展运行该函数的代码,例如,在处理每一行或什至小单元后检查禁用变量,如果您愿意,如果这是错误的,它运行 QThread。 sleep(100) 左右,然后醒来检查禁用。如果为假,则继续执行,否则休眠。

这是伪代码:

class MyThread (QThread):
    def run():
        isEnd = false
        while not isEnd:
            while disable:
                self.msleep(200)
            # Process next row
            # if we are done, isEnd = true

【讨论】:

@saardrimer:不用担心全局变量。他们肯定会在你的主窗口类中删除所有这些。我只是想让这个概念简单易懂。此外,您可能会在 for 迭代之前删除您的 qpushbutton,而不是在循环中不断检查它。不幸的是,findChildren 不允许排除模式,只能使用 QRegExp,但这很慢。 @saardrimer:一旦你理解了答案,你可能会改变你的看法。 ;) 或者至少,你可以告诉我为什么禁用并不意味着暂停你的书...... @saardrimer:如果你不能解释你的问题,它就不会真正得到解决。你的问题对我来说似乎是有效的,答案也是如此。老实说,到目前为止,我还看不到问题所在。除了单击按钮之外,您还想开始“暂停”吗?如果是这样,具体是什么?无论如何,您的问题可以在这方面使用一些帮助以便很好地理解。我以为按钮会启动“暂停”,这也会触发“恢复”。 我修改了问题。我希望现在更清楚我想要实现的目标。抱歉不清楚!

以上是关于在 Pyside 中执行函数期间等待按钮单击的主要内容,如果未能解决你的问题,请参考以下文章

如果结果已经可用,则仅在单击按钮时启动异步任务并执行操作,否则等待结果然后执行操作

在动作重定向 mvc 期间显示等待动画

Swift 3:在 ViewDidLoad 中从服务器获取信息,当单击按钮时,等待服务器的信息响应

量角器:单击按钮后如何等待页面完成?

在等待通知 std::condition_variable 期间执行“等待回调”

Sikuli如何用于等待按钮,直到它显示它然后单击它?