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



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

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



  • This post is deleted!

  • Lifetime Qt Champion

    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.



  • @SGaist ok,thank you very much!



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



  • @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();
    


  • @CN_Simo

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

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



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.