Python PyQt进度条忙
我发现了几个与此类似的问题,例如:Python PyQt进度条忙,python,multithreading,python-2.7,pyqt,qprogressbar,Python,Multithreading,Python 2.7,Pyqt,Qprogressbar,我发现了几个与此类似的问题,例如: 但大多数示例和答案都在一个GUI线程和一个数据处理线程上 让我解释一下我的情况 我有三门课: 类MainWindow(继承自QMainWindow类并充当主GUI) 类LogInWidget(继承自QWidgetclass。该类由所有用户名/密码字段+进度条组成,请参见下图) 3.class DataTableWidget(继承自QWidgetclass。由显示数十万数据的表组成) 该程序的设计目的是,一旦用户通过LogInWidget登录到该程序
QMainWindow
类并充当主GUI)QWidget
class。该类由所有用户名/密码字段+进度条组成,请参见下图)QWidget
class。由显示数十万数据的表组成)
该程序的设计目的是,一旦用户通过LogInWidget
登录到该程序,他将能够看到DataTableWidget
显示的所有数据
我使用.setCentralWidget
方法设置LogInWidget
和DataTableWidget
(即,如果用户密码正确,我使用
table = DataTableWidget ()
self.setCentralWidget(table)
显示表格
我的问题是:当用户登录时,在他看到数据表之前,有一个很大的GUI冻结,因为有太多的数据条目要通过表显示
因此,我想在程序加载完表之前显示一个繁忙的进度条(在我的LogInWidget
)
我曾想过使用
Qthread
来完成它,但由于显示进度条和创建DataTableWidget
并设置为centralwidget这两个任务都是GUI任务,我应该如何处理它呢?您必须将进度条值连接到DataTableWidget的信号。但这反过来又假设数据TableWidget在渲染时多次生成此信号,这是不可能的。也许您所需要的只是一种显示GUI正忙的方式,就像在条形图上有一条线在条形图的两端之间来回移动一样。这样,您就不需要在这两个小部件之间交换数据了。没有直接的方法可以做到这一点。如何操作有一个想法:
正如@schollii所说,在呈现时,您需要由DataTableWidget
发出一个信号。这样的信号并不存在。即使它存在,在呈现小部件之前也不会被处理
但是,如果DataTableWidget
有一个模型,您可以使用自己的方法覆盖data()
方法,该方法只调用基类的data()
方法,并更新进度条(尽管只在首次呈现表时更新进度条,而不是在随后调用data()
时更新进度条)。视图渲染时,视图将多次调用data()
方法。这样,您可以在渲染过程中访问时间点
当然,在控件返回到事件循环(渲染完成)之前,进度条不会重新绘制,但是您可以通过调用QApplication.processEvents()
来解决这个问题
请注意,这是一种非常粗糙的做法,通常是不好的做法,完全破坏了模型视图范例。我不建议这样做。但我想不出任何方法来实现相同的结果。。也许您可以加快
DataTableWidget
的呈现速度。例如,QTableView.resizeColumnsToContents()
被认为是很慢的。你在任何地方调用它吗?看看qt文档,搜索moveToThread
。我认为将qt GUI对象移动到另一个线程是不安全的。具体来说,它在这里说():虽然QObject是可重入的,但GUI类,尤其是QWidget及其所有子类,是不可重入的。它们只能从主线程使用。“。这似乎是一个很好的解决方案。您可以简单地将表模型的信号连接到qApp.processEvents
。模型的setData
方法必须发出dataChanged
,那么为什么不连接到它呢?@ekhumaro我不认为在显示的情况下会发出dataChanged
信号(渲染)已经充满数据的模型的视图。这个问题似乎表明,放缓来自于绘制视图,而不是用数据填充模型。不过,我可能错了。你可能是对的-问题还不完全清楚。