侧边栏壁纸
博主头像
陌上花 博主等级

回首万事皆休

  • 累计撰写 70 篇文章
  • 累计创建 11 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录
C++

QT对话框

种向日葵的人
2024-08-30 / 0 评论 / 0 点赞 / 35 阅读 / 0 字

Why

  • 基本上对话框其实就分为两种,一种是模态对话框另一种是非模态。最近外协的时候需要将原来的模态对话框转换成非模态对话框,因为QT本身的直接使用Show会发现,直接一闪而过了,看了一些他们的解释是说:因为显示之后直接析构了,这个指针就木有了,所以直接一闪而过。网上找的资料有的说直接在父类中创建一个指针,保证不会被析构,但是这个很容易就造成内存泄露了,所以后来发现使用EventLoop可以几乎完美的解决这个问题。

How

无返回值版本

  • 第一个版本是完全不需要在乎对话框的返回值的(因为外协代码不方便透露,所以以下都是直接简化的代码),此时需要自定义一个信号,然后在关闭的时候手动触发。
#include <QApplication>
#include <QWidget>
#include <QEventLoop>
#include <QCloseEvent>

class MyWidget : public QWidget {
    Q_OBJECT

public:
    MyWidget() {
        setWindowTitle("QEventLoop Example - Close to Exit");
    }

protected:
    void closeEvent(QCloseEvent* event) override {
        emit requestClose(); // 发送自定义信号,通知请求关闭事件循环
        event->accept();     // 接受事件,继续关闭窗口
    }

signals:
    void requestClose(); // 自定义信号,用于通知事件循环退出
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QEventLoop loop;

    MyWidget window;
    window.show();

    // 连接自定义信号到 QEventLoop 的 quit 槽
    QObject::connect(&window, &MyWidget::requestClose, &loop, &QEventLoop::quit);

    loop.exec(); // 启动局部事件循环

    return 0;
}

#include "main.moc"

有返回值版本

  • 这个版本需要关系返回值,确保既可以实现跟原来模态对话框一样可以有返回值,又可以跟其他界面的元素交互。这个时候需要注意connect的写法。
#include <QApplication>
#include <QWidget>
#include <QEventLoop>
#include <QCloseEvent>

class MyWidget : public QWidget {
    Q_OBJECT

public:
    MyWidget() {
        setWindowTitle("Custom Signal with QEventLoop Example");
    }

protected:
    void closeEvent(QCloseEvent* event) override {
        emit windowClosed(42); // 发射信号,传递返回值
        event->accept(); // 接受事件,关闭窗口
    }

signals:
    void windowClosed(int result); // 自定义信号,传递返回值
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MyWidget window;
    window.show();

    QEventLoop loop;
    int result = 0;

    QObject::connect(&window, &MyWidget::windowClosed, [&](int res) {
        result = res;
        loop.quit(); // 退出局部事件循环
    });

    loop.exec(); // 启动局部事件循环,窗口关闭时退出

    return result; // 返回结果
}

#include "main.moc"

Tips

  • 这个功能如果是在C#中其实基本是很简单就可以完成的,但是在QT中可能略微需要多加点代码了。但是其实问题不大,基本上这两种可以解决大部分的问题了。
0
博主关闭了所有页面的评论