【问题标题】:Qt 4.8 killing and restarting the GUIQt 4.8 杀死并重新启动 GUI
【发布时间】:2012-08-08 03:34:35
【问题描述】:

需要在基于 MIPS 的平台上编写 Qt 应用程序。

但是有很多限制。限制包括在需要时释放少量资源(QGFX 插件、GPU 内存等)并重新使用它。但是应用程序不能被杀死,因为它处理大量其他请求并运行其他事情。

基本上需要杀死GUI并释放所有与GUI相关的资源;稍后当需要时再次重新启动

已经尝试过的方法之一是:

main() -> 创建一个新线程

在新线程中,

while(<Condition>)
{
  sem_wait(..)
  m_wnd =  new myMainWindow();
   ...
   ..
   app->exec();
}

当有一个 kill 命令时,它会从事件循环中出来,并等待来自其他线程的信号。一旦其他线程进行了所需的更改,它将获取信号并创建一个新窗口并进入事件循环。

在 main() 中,还创建了一些其他线程,这些线程控制其他设备等并指示 Qt-GUI 的启动和停止。

以上似乎可行,但我不确定这是否是正确的设计。有什么问题吗?

谁能推荐更好的方法?

【问题讨论】:

  • 我建议在内存非常有限的系统上运行时,可能不应该使用 Qt。
  • 即使我们有内存,也有一些限制,我们如何使用它(特别是 GPU 内存、blitters、GPU)。当其他应用程序想要使用它时,由于其奇异设备模式,Qt 必须释放这些。

标签: qt qt4


【解决方案1】:

我能够在 Qt-Forums 中找到所需的答案。

由于主要目的是删除与 GUI(屏幕上)相关的所有内容,我可以使用 void setQuitOnLastWindowClosed ( bool quit ) (Details Here)。这将确保 GUI / 主窗口关闭,并且应用程序仍然没有退出事件循环,我可以稍后重新启动主窗口。

谢谢

【讨论】:

    【解决方案2】:

    当我需要一种方法来确保我的应用程序继续运行时,我将它分叉到一个子进程中。这样,即使它发生了段错误,主进程也会捕获它并启动一个新的子进程。在子进程中,我有多个线程用于 GUI 和非 GUI 任务。 fork 代码很短,基于wait(2) 手册页中给出的示例。 main() 只是在 while 循环中调用 createChild()createChild() 使用 zmain() 启动一个新进程。 zmain() 是您的 QT 应用程序的主要部分。

    #include <QtGui/QApplication>
    #include <QThread>
    
    int zmain(int argc, char *argv[])
    {
        QApplication app(argc, argv, true);
        app.setQuitOnLastWindowClosed(false);
    
        QThread powerThread;
        Power p;
        p.moveToThread(&powerThread);
        powerThread.start();
    
        return app.exec();
    }
    
    // The following code is taken from the wait(2) man page and has been modified to run
    // our Qt main() above in a child process. When the child terminates, it is automatically
    // restarted.
    
    #include <sys/wait.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    
    int createChild(int argc, char *argv[]) {
        pid_t cpid, w;
        int status;
    
        cpid = fork();
        if (cpid == -1) {
            perror("fork");
            exit(EXIT_FAILURE);
        }
    
        if (cpid == 0) {            /* Code executed by child */
            fprintf(stderr, "Child PID is %ld\n", (long) getpid());
            exit(zmain(argc, argv));
        } else {                    /* Code executed by parent */
            do {
                w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
                if (w == -1) {
                    perror("waitpid");
                    return(EXIT_FAILURE);
                }
    
                if (WIFEXITED(status)) {
                    fprintf(stderr, "exited, status=%d\n", WEXITSTATUS(status));
                } else if (WIFSIGNALED(status)) {
                    fprintf(stderr, "killed by signal %d\n", WTERMSIG(status));
                } else if (WIFSTOPPED(status)) {
                    fprintf(stderr, "stopped by signal %d\n", WSTOPSIG(status));
                } else if (WIFCONTINUED(status)) {
                    fprintf(stderr, "continued\n");
                }
            } while (!WIFEXITED(status) && !WIFSIGNALED(status));
            if (WIFEXITED(status) && WEXITSTATUS(status) == 111)
                return 111;
            return EXIT_SUCCESS;
        }
    }
    
    int
    main(int argc, char *argv[])
    {
        while (111 != createChild(argc, argv)) {
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-08-30
      • 1970-01-01
      • 2020-05-19
      • 2022-10-21
      • 2023-03-18
      • 1970-01-01
      • 2022-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多