Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用线程自动关闭PyQt/PySide窗口?_Python_Pyqt4_Pyside_Pyqt5_Pyside2 - Fatal编程技术网

Python 如何使用线程自动关闭PyQt/PySide窗口?

Python 如何使用线程自动关闭PyQt/PySide窗口?,python,pyqt4,pyside,pyqt5,pyside2,Python,Pyqt4,Pyside,Pyqt5,Pyside2,如何使PyQt5窗口在30秒后自动关闭,并且仍然保持窗口对交互的响应 我正在创建一个休眠30秒的线程,然后它调用窗口的close()函数。现在,代码挂起在self.close(): 请注意,Qt绑定导入就是这样做的,目的是让代码在您的终端上更容易运行;) 尝试以下代码而不是my\u win。执行函数线程化调用: class MyWindow(QtWidgets.QMainWindow): """Auto-closing window""" def __init__(self, p

如何使PyQt5窗口在30秒后自动关闭,并且仍然保持窗口对交互的响应

我正在创建一个休眠30秒的线程,然后它调用窗口的
close()
函数。现在,代码挂起在
self.close()


请注意,Qt绑定导入就是这样做的,目的是让代码在您的终端上更容易运行;)

尝试以下代码而不是
my\u win。执行函数线程化调用:

class MyWindow(QtWidgets.QMainWindow):
    """Auto-closing window"""
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        QtCore.QTimer.singleShot(30000, self.close)

原始代码无法工作的原因是禁止从辅助线程调用QtGUI方法(Qt方法不是线程安全的)。有几种解决方案,例如:

  • 使用
    QTimer
    (由于
    QTimer
    不使用线程,而只是将主线程中存在的Qt事件循环中的未来事件排队,因此此解决方案应解决segfaults-请参阅的答案)

  • 使用
    QThread
    和自定义Qt信号。Qt信号是线程安全的,因此您可以将次线程中的信号连接到主线程中的
    close
    插槽。然后,您可以在30秒后从次线程内发出信号以触发关闭

你应该采取的方法取决于你的最终目标(以及这个“玩具”的例子有多大),但现在我看不出有任何理由有第二个线程。您只需使用@ingvar的答案:)


另外,无论哪种方式,在Qt中使用python线程都是一个坏主意。坚持使用
QThread
,除非线程完全独立于GUI。

我已经测试了代码,并且它没有阻止小部件,您可以评论说,PyQt的版本,PyQt的版本Python@eyllanesc不知道你是什么意思,无论我测试的是Python版本还是Qt绑定/版本,窗口都会在这里崩溃。例如,我尝试了Python 2.7/PySide、Python 3.5/PyQt5,其中窗口崩溃。
import sys
import time
from threading import Thread

try:
    from PyQt5 import QtWidgets
except ImportError:
    try:
        from PySide2 import QtWidgets
    except ImportError:
        try:
            from PyQt4 import QtGui as QtWidgets
        except ImportError:
            try:
                from PySide import QtGui as QtWidgets
            except ImportError:
                print('giving up!')


class MyWindow(QtWidgets.QMainWindow):
    """Auto-closing window"""
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)

    def closeEvent(self, event):
        """Delete object when closed"""
        self.deleteLater()

    def auto_close(self, n):
        """Close self in n seconds"""
        print('going to sleep')
        for i in range(n):
            print('sleeping...')
            time.sleep(1)
        print('done sleeping!')
        self.close()  # hangs

    def execute_function_threaded(self, func):
        """Run given function in thread"""
        self.t = Thread(target=func)
        self.t.start()
        print('thread started')

app = QtWidgets.QApplication(sys.argv)
my_win = MyWindow()
my_win.show()
my_win.execute_function_threaded(func=lambda: my_win.auto_close(n=3))
sys.exit(app.exec_())
class MyWindow(QtWidgets.QMainWindow):
    """Auto-closing window"""
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        QtCore.QTimer.singleShot(30000, self.close)