有没有办法访问 QMainWindowPrivate 或 QMainWindowLayout?

发布于 2025-01-10 07:51:14 字数 580 浏览 0 评论 0原文

我正在使用 Qt5,我正在尝试执行此操作:

setCentralWidget(wid);
...
setCentralWidget(nullptr); // i don't want it to do deleteLater() for my wid variable
...
setCentralWidget(wid);

问题是,当我调用 setCentralWidget(nullptr) 时,它会为我的 执行 deleteLater() wid 变量。

因此,我找到了一种使用 setCentralWidget() 而不删除 wid 变量的方法:

Q_D(QMainWindow);
d->layout->setCentralWidget(nullptr);

但问题是:如何使用私有标头或小部件或其他什么?我的意思是,我无权访问 QMainWindowPrivate 或 QMainWindowLayout ,因为它们是私有的。那么有没有办法访问它们呢?

I'm using Qt5 and I am trying to do this:

setCentralWidget(wid);
...
setCentralWidget(nullptr); // i don't want it to do deleteLater() for my wid variable
...
setCentralWidget(wid);

The problem is that, when I call setCentralWidget(nullptr), it does deleteLater() for my wid variable.

So, I found a way to use setCentralWidget() without deleting the wid variable:

Q_D(QMainWindow);
d->layout->setCentralWidget(nullptr);

But the question is: How to use private headers or widgets or whatever? I mean, I don't have access to QMainWindowPrivate or QMainWindowLayout, because they are private. So is there a way to access them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

等风来 2025-01-17 07:51:14

OP 的问题是由使用 setCentralWidget(nullptr); 引起的。

QMainWindow::setCentralWiget()

将给定的小部件设置为主窗口的中央小部件。

注意:QMainWindow 获得小部件指针的所有权并在适当的时间将其删除。

(强调我的。)

因此,

setCentralWidget(wid);
...
setCentralWidget(nullptr);

必须预期 QMainWindow 将删除wid。否则,wid 实例可能会成为孤立实例,即内存泄漏。

然而,OP 问题可以在不冒险访问 QMainWindow 内部的情况下得到解决(这既不是有意的也没有必要)。

事实上,有一种替代方法可以删除中央小部件并再次接管所有权 - QMainWindow::takeCentralWidget():

从此主窗口中删除中央小部件。

已删除小部件的所有权将传递给调用者。

(再次强调我的。)

用于演示这一点的 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();
}

输出:
快照testQMainWindow-takeCentralWidget

OP's issue is caused by using 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.

(Emphasis mine.)

Hence, for

setCentralWidget(wid);
...
setCentralWidget(nullptr);

it has to be expected that the QMainWindow will delete the wid. Otherwise, the wid instance could become orphaned i.e. a memory leak.

However, OPs issue can be solved without adventurous accesses to internals of QMainWindow (which is neither intended nor necessary).

In fact, there is an alternative to remove the central widget and take over the ownership again – QMainWindow::takeCentralWidget():

Removes the central widget from this main window.

The ownership of the removed widget is passed to the caller.

(Emphasis mine, again.)

An MCVE to demonstrate this:

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

Output:
Snapshot of testQMainWindow-takeCentralWidget

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文