Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Chinese
  4. 在关闭事件accept执行前一步发送信号,窗口无法正常关闭,出现无响应
Qt 6.11 is out! See what's new in the release blog

在关闭事件accept执行前一步发送信号,窗口无法正常关闭,出现无响应

Scheduled Pinned Locked Moved Unsolved Chinese
关闭窗口无响应closeeventsignals & slotsqt5
7 Posts 3 Posters 7.5k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • CN_SimoC Offline
    CN_SimoC Offline
    CN_Simo
    wrote on last edited by CN_Simo
    #1

    问题如标题所述,代码如下:

    /*
        重构关闭函数
    */
    void MainWindow::closeEvent(QCloseEvent *event)
    {
        if(!QMessageBox::information(this,tr("关闭窗口"),tr("确定要退出程序?"),tr("确定"),tr("取消")))
        {
            if(QSqlDatabase::database().isOpen())
            {
                qDebug() << "Database is opening!" << endl;
                emit ui->action_close->trigger();    // 发送一个关闭数据库信号
               // QSqlDatabase::removeDatabase(QSqlDatabase::database().connectionName());
            }
            event->accept();
        }
        else
        {
            event->ignore();
        }
    }
    
    

    可能不是信号和槽的事情,当我直接执行槽函数的时候,依旧会无响应,槽函数如下:

    /*
        @SLOT
        在菜单栏上点击触发的信号槽-----断开
    */
    void MainWindow::on_action_close_triggered()
    {
        /*
            关闭数据库
        */
        QStringList dbList = QSqlDatabase::connectionNames();
        for(int i = 0; i < dbList.count(); ++i) {
        QSqlDatabase::removeDatabase(dbList[i]);
        }
    
        ui->statusBar->showMessage(tr("已关闭数据库连接!"));
    
    //    QString name;
    //    {
    //        name = QSqlDatabase::database().connectionName();
    //        QSqlDatabase::database().close();
    //    }//超出作用域,隐含对象QSqlDatabase::database()被删除。
    //    QSqlDatabase::removeDatabase(name);
    
        updateInterface(CloseMode);
    }
    

    只有直接执行关闭数据库的代码:

    QSqlDatabase::removeDatabase(QSqlDatabase::database().connectionName());
    

    才能正常关闭!

    错误演示:
    0_1505140545757_emit signal before execute the accept.gif

    joeQJ 1 Reply Last reply
    0
    • CN_SimoC Offline
      CN_SimoC Offline
      CN_Simo
      wrote on last edited by
      #2
      This post is deleted!
      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi and welcome to devnet,

        I've moved your post to the Chinese sub-forum so you will more likely get an answer in your native language.

        The forum official language is English.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        CN_SimoC 1 Reply Last reply
        1
        • SGaistS SGaist

          Hi and welcome to devnet,

          I've moved your post to the Chinese sub-forum so you will more likely get an answer in your native language.

          The forum official language is English.

          CN_SimoC Offline
          CN_SimoC Offline
          CN_Simo
          wrote on last edited by
          #4

          @SGaist ok,thank you very much!

          1 Reply Last reply
          0
          • CN_SimoC CN_Simo

            问题如标题所述,代码如下:

            /*
                重构关闭函数
            */
            void MainWindow::closeEvent(QCloseEvent *event)
            {
                if(!QMessageBox::information(this,tr("关闭窗口"),tr("确定要退出程序?"),tr("确定"),tr("取消")))
                {
                    if(QSqlDatabase::database().isOpen())
                    {
                        qDebug() << "Database is opening!" << endl;
                        emit ui->action_close->trigger();    // 发送一个关闭数据库信号
                       // QSqlDatabase::removeDatabase(QSqlDatabase::database().connectionName());
                    }
                    event->accept();
                }
                else
                {
                    event->ignore();
                }
            }
            
            

            可能不是信号和槽的事情,当我直接执行槽函数的时候,依旧会无响应,槽函数如下:

            /*
                @SLOT
                在菜单栏上点击触发的信号槽-----断开
            */
            void MainWindow::on_action_close_triggered()
            {
                /*
                    关闭数据库
                */
                QStringList dbList = QSqlDatabase::connectionNames();
                for(int i = 0; i < dbList.count(); ++i) {
                QSqlDatabase::removeDatabase(dbList[i]);
                }
            
                ui->statusBar->showMessage(tr("已关闭数据库连接!"));
            
            //    QString name;
            //    {
            //        name = QSqlDatabase::database().connectionName();
            //        QSqlDatabase::database().close();
            //    }//超出作用域,隐含对象QSqlDatabase::database()被删除。
            //    QSqlDatabase::removeDatabase(name);
            
                updateInterface(CloseMode);
            }
            

            只有直接执行关闭数据库的代码:

            QSqlDatabase::removeDatabase(QSqlDatabase::database().connectionName());
            

            才能正常关闭!

            错误演示:
            0_1505140545757_emit signal before execute the accept.gif

            joeQJ Offline
            joeQJ Offline
            joeQ
            wrote on last edited by joeQ
            #5

            @CN_Simo 您好,欢迎来到Qt社区。

            根据您的问题描述,进行以下思考:

            1. signal and slot 是否链接成功。 信号是否成功被slots接受,可以在slot中qDebug信息,您也可以设置断点进行调试;
            2. 注意 在slot函数中, 确保发射的object没有提前销毁。 有的情况下, 信号发射完后,该对象立刻销毁,导致槽函数中的对象失效。
            3. 如果signal object and slot object 在不同的线程, 可以尝试 在connect函数中,添加此变量。

            Qt::DirectConnection : The slot is invoked immediately when the signal is emitted. The slot is executed in the signalling thread.

            Just do it!

            CN_SimoC 1 Reply Last reply
            0
            • joeQJ joeQ

              @CN_Simo 您好,欢迎来到Qt社区。

              根据您的问题描述,进行以下思考:

              1. signal and slot 是否链接成功。 信号是否成功被slots接受,可以在slot中qDebug信息,您也可以设置断点进行调试;
              2. 注意 在slot函数中, 确保发射的object没有提前销毁。 有的情况下, 信号发射完后,该对象立刻销毁,导致槽函数中的对象失效。
              3. 如果signal object and slot object 在不同的线程, 可以尝试 在connect函数中,添加此变量。

              Qt::DirectConnection : The slot is invoked immediately when the signal is emitted. The slot is executed in the signalling thread.

              CN_SimoC Offline
              CN_SimoC Offline
              CN_Simo
              wrote on last edited by
              #6

              @joeQ
              已经大概知道了由什么引起的无响应了!

              我的做法是: 我在槽函数中各处多放了几个qDebug,然后发现在下面这句代码前的qDebug都能输出,之后就出现了无响应

              ui->statusBar->showMessage(tr("已关闭数据库连接!"));
              

              就这么看的话,在关闭事件accept之后,这个ui可能被销毁了,所以再使用ui里的东西会造成无响应。

              但是还是有一点疑问,就是关闭事件accept明显是发生再触发槽之后的,ui怎么就被销毁了?是不同线程的操作吗?

              // 摘自在closeEvent()函数中
              if(QSqlDatabase::database().isOpen())
              {
                  qDebug() << "Database is opening!" << endl;
                  emit ui->action_close->trigger();    // 发送一个关闭数据库信号
              }
              
              event->accept();
              
              joeQJ 1 Reply Last reply
              0
              • CN_SimoC CN_Simo

                @joeQ
                已经大概知道了由什么引起的无响应了!

                我的做法是: 我在槽函数中各处多放了几个qDebug,然后发现在下面这句代码前的qDebug都能输出,之后就出现了无响应

                ui->statusBar->showMessage(tr("已关闭数据库连接!"));
                

                就这么看的话,在关闭事件accept之后,这个ui可能被销毁了,所以再使用ui里的东西会造成无响应。

                但是还是有一点疑问,就是关闭事件accept明显是发生再触发槽之后的,ui怎么就被销毁了?是不同线程的操作吗?

                // 摘自在closeEvent()函数中
                if(QSqlDatabase::database().isOpen())
                {
                    qDebug() << "Database is opening!" << endl;
                    emit ui->action_close->trigger();    // 发送一个关闭数据库信号
                }
                
                event->accept();
                
                joeQJ Offline
                joeQJ Offline
                joeQ
                wrote on last edited by
                #7

                @CN_Simo

                您是在MainWindow的close事件中,发射信号进行清理关闭工作的。

                Qt signal and slot确实很方便。 可是有时候也会造成一些不必要的麻烦。很多时候,也可以传递对象的指针,直接在对应的地方调用对象的函数即可。

                Just do it!

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved