【问题标题】:Why does close() only work in one method and not the other?为什么 close() 只适用于一种方法而不适用于另一种方法?
【发布时间】:2013-04-20 23:33:00
【问题描述】:

主窗口.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void test();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

主窗口.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

void MainWindow::test()
{
    close(); // Line 1
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    close(); // Line 2
}

main.cpp:

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    w.test();

    return a.exec();
}

如果我注释掉第 2 行中的 close(),第 1 行中的 close() 将关闭窗口并让应用程序继续运行。

如果我注释掉第 1 行中的 close(),第 2 行中的 close() 将关闭窗口并结束应用程序。

为什么会有这种行为差异?

【问题讨论】:

    标签: c++ qt qt5


    【解决方案1】:

    原因是在事件循环开始之前调用了w.test()(a.exec()),所以它不会导致任何其他可能与close()操作QMainWindow相关的事件发生。

    在第二种方法中,您的 close() 函数将在事件循环启动后调用,更好地说,在您的事件循环中(当您单击按钮时,您将被调度到 on_pushButton_clicked() 方法和 @987654328 @ 将通知您的应用程序需要结束它。

    为了在事件循环中运行test() 函数,请使用单次计时器:

    //Qt 4 - in Qt 5, you can work this out without helper slot:
    
    class MainWindow: public QMainWindow{
        //...   
        void test();
        //...
    public slots:
        void testHelper(){ test(); }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        QTimer::singleShot(0, &w, SLOT(testHelper()));
    
        return a.exec();
    }
    

    编辑

    看来Qt5新的connect语法在这里帮不了你避免额外的槽[1]

    Qt5 具有允许使用 lambda 的新连接语法,而 QtConcurrent 已经能够使用 lambda QTimer 或更具体地说 QTimer::singleShot() 缺少这两者。 为 QTimer::singleShot() 提供函数指针语法和 lambda 支持会很方便(且一致)。

    编辑 2

    更准确地说,当您调用QMainWindow::close() 时,会引发QMainWindow::closeEvent(QCloseEvent *) 事件,通常应该在当前事件循环中进行处理。由于在调用close的时候没有事件循环,所以这个事件没有被追上,不会导致应用退出。

    【讨论】:

    • 感谢您的解释,而不是仅仅给出解决方案。
    猜你喜欢
    • 2014-07-21
    • 2014-01-21
    • 2023-01-25
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多