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执行前一步发送信号,窗口无法正常关闭,出现无响应
QtWS25 Last Chance

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

Scheduled Pinned Locked Moved Unsolved Chinese
关闭窗口无响应closeeventsignals & slotsqt5
7 Posts 3 Posters 6.6k Views
  • 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.
  • C Offline
    C Offline
    CN_Simo
    wrote on 11 Sept 2017, 14:40 last edited by CN_Simo 9 Nov 2017, 14:49
    #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

    J 1 Reply Last reply 12 Sept 2017, 01:05
    0
    • C Offline
      C Offline
      CN_Simo
      wrote on 11 Sept 2017, 14:45 last edited by
      #2
      This post is deleted!
      1 Reply Last reply
      0
      • S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 11 Sept 2017, 14:56 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

        C 1 Reply Last reply 11 Sept 2017, 15:06
        1
        • S SGaist
          11 Sept 2017, 14:56

          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.

          C Offline
          C Offline
          CN_Simo
          wrote on 11 Sept 2017, 15:06 last edited by
          #4

          @SGaist ok,thank you very much!

          1 Reply Last reply
          0
          • C CN_Simo
            11 Sept 2017, 14:40

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

            /*
                重构关闭函数
            */
            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

            J Offline
            J Offline
            joeQ
            wrote on 12 Sept 2017, 01:05 last edited by joeQ 9 Dec 2017, 01:17
            #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!

            C 1 Reply Last reply 12 Sept 2017, 02:27
            0
            • J joeQ
              12 Sept 2017, 01:05

              @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.

              C Offline
              C Offline
              CN_Simo
              wrote on 12 Sept 2017, 02:27 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();
              
              J 1 Reply Last reply 12 Sept 2017, 02:49
              0
              • C CN_Simo
                12 Sept 2017, 02:27

                @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();
                
                J Offline
                J Offline
                joeQ
                wrote on 12 Sept 2017, 02:49 last edited by
                #7

                @CN_Simo

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

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

                Just do it!

                1 Reply Last reply
                0

                7/7

                12 Sept 2017, 02:49

                • Login

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