有没有办法访问 QMainWindowPrivate 或 QMainWindowLayout?
Is there a way to access QMainWindowPrivate or QMainWindowLayout?
我正在使用 Qt5,我正在尝试这样做:
setCentralWidget(wid);
...
setCentralWidget(nullptr); // i don't want it to do deleteLater() for my wid variable
...
setCentralWidget(wid);
问题是,当我调用 setCentralWidget(nullptr)
时,它会为我的 wid
变量执行 deleteLater()
。
所以,我找到了一种在不删除 wid
变量的情况下使用 setCentralWidget()
的方法:
Q_D(QMainWindow);
d->layout->setCentralWidget(nullptr);
但问题是:如何使用私有 headers 或小部件或其他什么?我的意思是,我无权访问 QMainWindowPrivate
或 QMainWindowLayout
,因为它们是私有的。那么有没有办法访问它们?
OP 的问题是由使用 setCentralWidget(nullptr);
.
引起的
QMainWindow::setCentralWiget():
Sets the given widget to be the main window's central widget.
Note: QMainWindow takes ownership of the widget pointer and deletes it at the appropriate time.
(强调我的。)
因此,
setCentralWidget(wid);
...
setCentralWidget(nullptr);
必须预料 QMainWindow
会删除 wid
。否则,wid
实例可能会成为孤儿,即内存泄漏。
但是,无需冒险访问 QMainWindow
的内部结构(这既无意也不必要)也可以解决 OP 问题。
事实上,有一个替代方案可以删除中央小部件并再次接管所有权 – QMainWindow::takeCentralWidget():
Removes the central widget from this main window.
The ownership of the removed widget is passed to the caller.
(再次强调我的。)
一个 MCVE 来证明这一点:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QMainWindow qWinMain;
qWinMain.setWindowTitle("QMainWindow::takeCentralWidget");
QLabel *pQLbl = new QLabel("The\ncentral\nwidget");
pQLbl->setAlignment(Qt::AlignCenter);
qWinMain.setCentralWidget(pQLbl);
qWinMain.show();
QTimer qTimer;
qTimer.setInterval(1000);
uint n = 10;
// install signal handlers
QObject::connect(&qTimer, &QTimer::timeout,
[&]() {
--n;
if (!n) {
qWinMain.setCentralWidget(nullptr);
app.quit();
} else if (n & 1) qWinMain.setCentralWidget(pQLbl);
else qWinMain.takeCentralWidget();
});
// runtime loop
qTimer.start();
return app.exec();
}
输出:
我正在使用 Qt5,我正在尝试这样做:
setCentralWidget(wid);
...
setCentralWidget(nullptr); // i don't want it to do deleteLater() for my wid variable
...
setCentralWidget(wid);
问题是,当我调用 setCentralWidget(nullptr)
时,它会为我的 wid
变量执行 deleteLater()
。
所以,我找到了一种在不删除 wid
变量的情况下使用 setCentralWidget()
的方法:
Q_D(QMainWindow);
d->layout->setCentralWidget(nullptr);
但问题是:如何使用私有 headers 或小部件或其他什么?我的意思是,我无权访问 QMainWindowPrivate
或 QMainWindowLayout
,因为它们是私有的。那么有没有办法访问它们?
OP 的问题是由使用 setCentralWidget(nullptr);
.
QMainWindow::setCentralWiget():
Sets the given widget to be the main window's central widget.
Note: QMainWindow takes ownership of the widget pointer and deletes it at the appropriate time.
(强调我的。)
因此,
setCentralWidget(wid);
...
setCentralWidget(nullptr);
必须预料 QMainWindow
会删除 wid
。否则,wid
实例可能会成为孤儿,即内存泄漏。
但是,无需冒险访问 QMainWindow
的内部结构(这既无意也不必要)也可以解决 OP 问题。
事实上,有一个替代方案可以删除中央小部件并再次接管所有权 – QMainWindow::takeCentralWidget():
Removes the central widget from this main window.
The ownership of the removed widget is passed to the caller.
(再次强调我的。)
一个 MCVE 来证明这一点:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QMainWindow qWinMain;
qWinMain.setWindowTitle("QMainWindow::takeCentralWidget");
QLabel *pQLbl = new QLabel("The\ncentral\nwidget");
pQLbl->setAlignment(Qt::AlignCenter);
qWinMain.setCentralWidget(pQLbl);
qWinMain.show();
QTimer qTimer;
qTimer.setInterval(1000);
uint n = 10;
// install signal handlers
QObject::connect(&qTimer, &QTimer::timeout,
[&]() {
--n;
if (!n) {
qWinMain.setCentralWidget(nullptr);
app.quit();
} else if (n & 1) qWinMain.setCentralWidget(pQLbl);
else qWinMain.takeCentralWidget();
});
// runtime loop
qTimer.start();
return app.exec();
}
输出: