在 PyQt5 中通过命令行调用外部程序时,有没有办法阻止 GUI 冻结?

Posted

技术标签:

【中文标题】在 PyQt5 中通过命令行调用外部程序时,有没有办法阻止 GUI 冻结?【英文标题】:Is there a way to stop the GUI from freezing when calling an external program via command line in PyQt5? 【发布时间】:2020-06-23 11:08:00 【问题描述】:

我一直在尝试为项目创建 GUI。我有一个“exe”文件,我需要通过按一下按钮在应用程序的后台运行它。我使用 qprocess 创建了一个基于线程的函数调用 exe 文件,它可以工作。但问题是,它冻结了 GUI,并且在尝试多个文件时总是显示没有响应......

有什么方法可以重新路由 Qprocess,使其不会阻塞 GUI,而我仍然可以以某种方式访问​​ Qprocess exe 文件输出?

Edit#1:exe 文件的进程与用户提供的“配体文件”的数量成正比。为了测试,我必须提供至少 100 个左右的文件。这会在 GUI 上造成足够的冻结,以至于它只是说在任务栏上没有响应。

class Main(QtWidgets.QMainWindow, Ui_MainWindow):
    def testMain(self):
        ligands = glob.glob("*.sdf")
        liglen = len(ligands)
        self.files_2.setText("<b>1/ Ligand(s)</b>".format(liglen))
        x = self.progressBar.setMaximum(liglen)
        t = threading.Thread(target = self.ligconv(ligands))
        t.start()
    def ligconv (self, ligands):
        process = QProcess()
        cd = "babel.exe"
        for i in ligands:
            tem = re.sub('\..*', '.pdbqt', i)
            ligename = tem
            ar = [receptorname, "-xnrcp", "-O", ligname]
            process.execute(cd, ar)

后记

我知道一按按钮,通过cmd路由的exe文件就被赋予了控制权。 我也知道使用 Qpr​​ocess waitFor 命令会阻塞 GUI,因此我已经从代码中删除了它们。 抱歉,我不能真正展示我正在使用的代码,因为它是一个重要的项目,这是相同的最小代码:)

【问题讨论】:

如果您不向我们展示任何代码,我们将无法为您提供帮助:这种行为可能有多种原因,我们无法猜测。根据您当前的逻辑创建一个新脚本,以便您可以向我们提供minimal, reproducible example,并用它来编辑您的问题。 【参考方案1】:

您正在主线程中执行t = threading.Thread(target = self.ligconv(ligands)),因为您的代码相当于:

res = self.ligconv(ligands)
t = threading.Thread(target = res)

相反,目标必须接收一个可调用的,如果你想传递额外的参数,那么你应该使用 args:

t = threading.Thread(target=self.ligconv, args=(ligands,))

【讨论】:

这只是关闭 GUI 并尝试在后台执行 exe 文件。不过感谢您的帮助..

以上是关于在 PyQt5 中通过命令行调用外部程序时,有没有办法阻止 GUI 冻结?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 vb.Net 中通过外部扬声器播放声音?

在C中通过命令行传递整数?

如何在 PyQt5 中通过拖放来绘制矩形并调整其形状

在 C# 中通过远程处理获取外部 IP 地址

在 PyQt5 中通过对象#id 设置样式

Ubuntu中通过SuperVisor添加守护进程