2

有时我的 QProgressDialog 显示,有时它根本不显示(好像没有调用 processEvents)。processEvents() 命令是否有任何工件可能导致 QProgressDialog 在某些情况下不显示?

我的问题很笼统,因为我还不能在我的代码中隔离问题。但是,我注意到当我使用配置解析器访问文本文件时,当我的 QProgressDialog 未显示时会发生这种情况。解决方法是在文件关闭后执行 time.sleep()(也许是为了确保过程完成并且 processEvents 将开始显示 QProgressDialog)。

如果有帮助,这是我将 QProgressDialog 作为生成器运行的代码:

def progress_dialog(self, data, label, window_title, stop_label, capture_bar=False):
    bar = QProgressDialog(label, stop_label, 0, len(data))
    if capture_bar: self.prog_bar = bar
    bar.setWindowTitle(window_title)
    for k, d in enumerate(data):
        QCoreApplication.instance().processEvents()
        if bar.wasCanceled():
            raise GeneratorExit
        # set the next value beyond the start of 0
        bar.setValue(k+1)
        # again process events to draw the new label and value
        QCoreApplication.instance().processEvents()
        yield(d)
        raise StopIteration

再次,对不起,我没有孤立问题的完整代码片段(并且完整代码太大了)。我想我正在寻找的是为什么要检查 processEvents() 命令是否正在执行其工作(因为很明显我正在调用它,但它挂在其他进程上而不是显示对话框)。

编辑:

根据此支持请求,执行“bar.show()”命令将强制显示进度条。

http://redmine.smar.fi/issues/265

我将等待几周,并确保这是一个有保证的修复,然后再将其发布为答案。

4

3 回答 3

3

如果您需要显示一个QProgessDialog而不考虑进程的持续时间,请使用其值为 0 的setMinimumDuration方法。根据文档,默认最小值为 4000 毫秒。

于 2013-11-05T22:59:32.003 回答
1

根据此支持请求,执行bar.show()命令将强制显示进度条: http ://redmine.smar.fi/issues/265

只需show()在每次process events调用之前和首次构建进度条之后调用该方法。

我已经等了将近 4 个月了,这个解决方案还没有失败。似乎是一个足够的答案。

于 2014-02-26T02:18:14.490 回答
1

这可能是一个旧线程,但我遇到了类似的问题,show() 使对话框出现,但为空。所以,我想出了这个装饰器,我将它应用于我想要运行阻塞的函数,同时允许 GUI 线程处理事件。

def nongui(fun):
    """Decorator running the function in non-gui thread while
    processing the gui events."""
    from multiprocessing.pool import ThreadPool
    from PyQt4.QtGui import QApplication

    def wrap(*args, **kwargs):
        pool = ThreadPool(processes=1)
        async = pool.apply_async(fun, args, kwargs)
        while not async.ready():
            async.wait(0.01)
            QApplication.processEvents()
        return async.get()

    return wrap

然后,很容易用装饰器正常编写计算函数:

@nongui
def work(input):
    # Here you calculate the output and set the 
    # progress dialog value
    return out

然后像往常一样运行它:

out = work(input)
于 2015-05-07T06:03:04.403 回答