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();
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
中可能略微需要多加点代码了。但是其实问题不大,基本上这两种可以解决大部分的问题了。