有没有办法访问 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 或小部件或其他什么?我的意思是,我无权访问 QMainWindowPrivateQMainWindowLayout,因为它们是私有的。那么有没有办法访问它们?

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();
}

输出: