简体   繁体   English

以编程方式干净地关闭qt Gui应用程序

[英]Cleanly closing a qt Gui application application programatically

Hello I've been using PyQt 4.8 on windows to create a simple gui application. 您好我一直在Windows上使用PyQt 4.8来创建一个简单的gui应用程序。 The gui(main window) has one button, and one QLineEdit widget. gui(主窗口)有一个按钮和一个QLineEdit小部件。 Pressing the button simply calls a function to process the contents of the QLineEdit widget. 按下按钮只需调用一个函数来处理QLineEdit小部件的内容。 So far it works well. 到目前为止它运作良好。 My main looks like this 我的主要看起来像这样

class StartQt4App(QtGui.QMainWindow):

    def process_stuff(self,param):
        #Do stuff here


if __name__="__main__":
    app=QtGui.QApplications(sys.argv)
    myapplication=StartQt4App()
    myapplication.show()
    sys.exit(app.exec_())

Using py2exe I can create an windows executable eg mygui_app.exe However I want to adapt it so that it can be run from the windows command line. 使用py2exe我可以创建一个Windows可执行文件,例如mygui_app.exe但是我想调整它以便它可以从windows命令行运行。 ie if the user types 即如果用户输入

Run mygui_app.exe "c:\\text_file.txt" 运行mygui_app.exe“c:\\ text_file.txt”

The application launches, this time without the GUI and automatically processes the parameter that was entered when the application was called. 应用程序启动,这次没有GUI并自动处理调用应用程序时输入的参数。

So far this is what I have come up with 到目前为止,这是我想出的

class StartQt4App(QtGui.QMainWindow):

    def process_stuff(self,param):
        #Do stuff here

    def process_stuff_again(self,param):
        #Do stuff here
        return


if __name__="__main__":
    if len(sys.argv)==1:

        app=QtGui.QApplications(sys.argv)
        myapplication=StartQt4App()
        myapplication.show()
        sys.exit(app.exec_())
    else:
        app=QtGui.QApplications(sys.argv)
        myapplication=StartQt4App()
        myapplication.process_stuff_again(param)
        sys.exit(app.exec_())

Essentially if the application has been called with parameters I don't want/need to show the gui, simply call the processing function. 基本上如果使用参数调用应用程序我不想/需要显示gui,只需调用处理函数即可。 Once processing is done exit cleanly 处理完成后,干净地退出

Currently it works, at least as far as processing the file goes. 目前它的工作原理,至少就处理文件而言。 However it does not exit, once the processing is complete. 但是,一旦处理完成,它就不会退出。 Instead the program remains active (I can see it using the Windows Task Manager). 而是程序保持活动状态(我可以使用Windows任务管理器看到它)。

My question is how do I programatically quit the application? 我的问题是如何以编程方式退出应用程序? so that once done it cleanly shuts itself down. 所以,一旦完成它干净地关闭自己。

I have experimented with 我已经尝试过

  • app.quit() app.quit()
  • app.exit() app.exit()
  • myapplication.exit() myapplication.exit()
  • myapplication.quit() myapplication.quit()

None work, essentially the application is still alive and kicking. 没有工作,基本上应用程序仍然活着和踢。 In desperation I removed the 无奈之下,我删除了

sys.exit(app.exec_()) sys.exit(app.exec_())

from the else portion of the code and now it just crashes, as it it processes the file and then promptly crashes. 从代码的else部分,现在它只是崩溃,因为它处理文件,然后迅速崩溃。 Very consistently crashes. 非常一致的崩溃。

Any suggestion as to how to cleanly get the application to close nicely when its called from the command line? 关于如何从命令行调用应用程序以干净利落地关闭应用程序的任何建议?

Not really familiar with PyQt, probably you're doing something wrong in your processing function which leads your app crashed. 不太熟悉PyQt,可能你在处理函数中做错了导致你的应用程序崩溃。

Also, in case you processing something synchronously, your 此外,如果你同步处理某些事情,你的

app.quit() app.quit()

called before 以前叫过

app.exec_() app.exec_()

and doesn't have any effect because event loop (that started with app.exec_()) not started yet. 并且没有任何效果,因为事件循环(以app.exec_()开头)尚未启动。

If you still need to have event loop started before your processing function called (ie you're using event loop in your processing function), you can do a quirk like this (it's C++, I'm not familiar with PyQt): 如果你仍然需要在调用处理函数之前启动事件循环(即你在处理函数中使用事件循环),你可以像这样做一个怪癖(它是C ++,我不熟悉PyQt):

#include <QCoreApplication>
#include <QTimer>
#include <QDebug>

class MyApp : public QObject
{
    Q_OBJECT
public slots:
    void process()
    {
        qDebug() << "Processing...";
        qDebug() << "Quit application...";
        qApp->quit();;
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    MyApp myapp;
    QTimer::singleShot(0, &myapp, SLOT(process()));
    int rc = a.exec();
    qDebug() << "app finished with" << rc << "code";
}

#include "main.moc"

Also, QMainWindow class doesn't have quit/exit methods (at least in C++). 此外,QMainWindow类没有退出/退出方法(至少在C ++中)。

If you don't need to show the GUI, do you even need to run the QApplication event loop at all? 如果您不需要显示GUI,您甚至需要运行QApplication事件循环吗? You could just make process_stuff_again a staticmethod 你可以让process_stuff_again成为一个staticmethod

class StartQt4App(...):
    @staticmethod
    def process_stuff_again(param):
        ...

app = QtGui.QApplication(sys.argv)
StartQt4App.process_stuff_again(param)

If you're not using any of the Qt classes in process_stuff_again , you don't even need to create the QApplication . 如果您没有在process_stuff_again使用任何Qt类,则甚至不需要创建QApplication

Or if you really need to create an instance of the main window and you absolutely need the event loop, just make sure to call .close on the window at the end of the method. 或者,如果您确实需要创建主窗口的实例并且您绝对需要事件循环,请确保在方法结束时的窗口上调用.close By default, the QApplication should exit when no windows are left open. 默认情况下, QApplication应在没有打开窗口时退出。

def process_stuff_again(self, param):
    ...
    self.close()

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

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