简体   繁体   English

如何安全退出 pyqt 应用程序 python

[英]How to safely quit pyqt application python

I have a pyqt5 project.我有一个pyqt5项目。 I am starting the window in full screen mode.我正在全屏模式下启动 window。 It is working but because it full screen so I cannot click on x button to close it so I have to press alt-f4 to close it.它正在工作,但因为它是全屏的,所以我不能点击x按钮来关闭它,所以我必须按alt-f4来关闭它。 It works fine but now I have another class running in the project due to which when I press alt-f4 , it closes the window but still looks the thread didnt closed due to which it stays in the terminal.它工作正常,但现在我在项目中运行了另一个 class ,因此当我按下alt-f4时,它关闭了 window 但仍然看起来线程没有关闭,因为它停留在终端中。 Below is the code:下面是代码:

class RecognizeFaceInFrame(Thread):

    def __init__(self):
        super().__init__()

        self.get_face_name = False
        self.stop_face_thread = False

    def recognize_face_frame(self):
        try:
            if self.get_face_name:
                #SOME CODE
            time.sleep(1)
        except Exception as e:
            print("Exception occurred in recognize face {}".format(e))

    def run(self):
        while not self.stop_face_thread:
            self.recognize_face_frame()

class TRIANGLE(QMainWindow, Ui_MainWindow):
    def __init__(self):
        # SOME CODE
        self.showFullScreen()

        self.timer = QTimer()
        self.timer.timeout.connect(self.view_cam)
        self.timer.start(20)
        self.frame_count = 0

        self.face_recog_thread = RecognizeFaceInFrame()  
        self.face_recog_thread.start()

    def __del__(self):
        self.timer.stop()
        self.face_recog_thread.stop_face_thread = True

    def view_cam(self):
        # SOME CODE


app = QApplication(sys.argv)
app.setStyle('Windows')
main_window = TRIANGLE()
main_window.show()
sys.exit(app.exec_())

I have a class RecognizeFaceInFrame which I am initializing in __init__ in TRIANGLE class.我有一个 class RecognizeFaceInFrame ,我在TRIANGLE class 的__init__中初始化它。 Function recognize_face_frame will start execution if we set get_face_name to True .如果我们将get_face_name设置为Truerecognize_face_frame identify_face_frame 将开始执行。 If we set stop_face_thread to True , this thread will close automatically and thus I have put this in __del__ of TRAINGLE but when I am pressing alt-f4 it doesn't closes.如果我们将stop_face_thread设置为True ,该线程将自动关闭,因此我已将其放在__del__TRAINGLE中,但是当我按下alt-f4时它不会关闭。 Can anyone please help me understand what I should do here to safely close all the threads and application.谁能帮我理解我应该在这里做什么来安全地关闭所有线程和应用程序。 Please help.请帮忙。 Thanks谢谢

How about using closeEvent ?使用closeEvent怎么样?

Classes inheriting Qt modules are removed by Qt's own garbage collector - at least link says so. Qt 自己的垃圾收集器删除了继承 Qt 模块的类 - 至少链接是这样说的。 Therefore, UI Object is not immediately deleted.因此,UI Object 不会立即删除。

Change PySide2 to PyQt and try this.将 PySide2 更改为 PyQt 并尝试此操作。 Function closeEvent will run as soon as you hit alt+f4. Function closeEvent 将在您按下 alt+f4 后立即运行。 Until then, thread will keep printing out message to console.在那之前,线程将继续向控制台打印消息。

from PySide2.QtWidgets import QWidget, QApplication, QTextEdit, QVBoxLayout
from PySide2.QtGui import QCloseEvent
from threading import Thread
import sys
import time


class TestThread(Thread):

    def __init__(self):
        super().__init__()
        self.stop_thread = False

    def run(self):
        while not self.stop_thread:
            print("I'm alive!")
            time.sleep(1)

        print("Dead! Not a big surprise.")


class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.test_thread = TestThread()
        self.test_thread.start()

    def closeEvent(self, event:QCloseEvent):
        self.test_thread.stop_thread = True



if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

Result:结果:

I'm alive!我还活着!
I'm alive!我还活着!
I'm alive!我还活着!
Dead.死的。 Not a big surprise.不是什么大惊喜。

Process finished with exit code -1进程以退出代码 -1 结束

You can also use the aboutToQuit signal from QApplication.您还可以使用来自 QApplication 的aboutToQuit信号。 Just connect it to your cleanup methods.只需将其连接到您的清理方法即可。 See docs.请参阅文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM