QWidget 如何获得“整个”父级?

Posted

技术标签:

【中文标题】QWidget 如何获得“整个”父级?【英文标题】:How can a QWidget get the "entire" parent? 【发布时间】:2013-07-17 20:28:46 【问题描述】:

我在 MainWindow.cpp 中实例化了一个 widgetClass。我想将“this”传递给这个小部件,不仅仅是(QWidget* 父级),还有(MainWindow* 父级)。但是在构建时,widgetClass 是在 MainWindow 之前建立的,因此它会出错。

我想访问 MainWindow 中的 instanceVariables??

即:

myWidget(QWidget* parent, MainWindow* parent);

【问题讨论】:

我不确定我是否理解正确,如果我没有理解,请改写问题,但我认为您需要 QMainWidndow 派生类的 setCentralWidget 成员函数:qt-project.org/doc/qt-5.0/qtwidgets/…,QMainWindow 已经有一个布局,这就是为什么你需要把你的小部件作为 centralWidget。 在另一种情况下(你所说的关于访问主窗口功能的事情)你不需要传递 MainWindow 指针,只需在 MainWindow 和 widgetClass 中为你需要的功能编写信号和槽并将它们连接起来。 【参考方案1】:

此类任务存在一些问题..也许问题是您必须使用Forward Declaration 将一个类包含在另一个包含第一个类的类中.. 或者QWidget 的默认构造函数可能具有第一个参数作为默认参数。你的错误到底是什么?

不管怎样,这里有一个完整的例子:

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "mywidget.h"

namespace Ui 
class MainWindow;


class MainWindow : public QMainWindow

    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    int foo(int n);
private:
    Ui::MainWindow *ui;

    MyWidget *w;
;

#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

    ui->setupUi(this);
    w = new MyWidget(this);
    this->setCentralWidget(w);


MainWindow::~MainWindow()

    delete ui;


int MainWindow::foo(int n)

    std::cout << "foo" << std::endl;
    return n+42;

mywidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

class MainWindow;

class MyWidget : public QWidget

    Q_OBJECT
public:
    explicit MyWidget(MainWindow *main, QWidget *parent = 0);
signals:
public slots:
;

#endif // MYWIDGET_H

mywidget.cpp

#include "mywidget.h"
#include "mainwindow.h"
#include <iostream>

MyWidget::MyWidget(MainWindow *main, QWidget *parent) :
    QWidget(parent)

    std::cout << main->foo(0) << std::endl;

这有帮助吗?

【讨论】:

不确定 MyWidget 在父级中的传递位置?其余的似乎在流动。 在 MyWindget 中,您有 MainWindow 的引用为 *main,您可以调用 MainWindow 的特定方法 (foo)。在 MainWindow 中,您有一个 MyWidget 的实例为 *q.. Parent 并没有真正触及,它是由 setCentralWidget.. 自动设置的。【参考方案2】:

answer proposed by nkint 是最干净的方法。但是,如果您没有时间或无法更改软件的架构,则存在快速破解:

如果您确定MyWidget 的父级是QMainWindow,您可以这样做:

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent)

    QMainWindow * main = static_cast<QMainWindow*>(parent);
    std::cout << main->foo(0) << std::endl;

如果您不确定,即实际上可能是也可能不是QMainWindow,那么您可以这样做:

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent)

    QMainWindow * main = qobject_cast<QMainWindow*>(parent);
    // here, main is null if and only if parent was not a QMainWindow
    if(main)
        std::cout << main->foo(0) << std::endl;

qobject_cast 类似于dynamic_cast。更准确地说,文档说:

qobject_cast() 函数的行为类似于标准 C++ dynamic_cast(),其优点是它不需要 RTTI 支持并且可以跨动态库边界工作。

qobject_cast() 也可以和接口一起使用;有关详细信息,请参阅 Plug & Paint 示例。

警告:如果 T 未使用 Q_OBJECT 宏声明,则此函数的返回值未定义。

【讨论】:

以上是关于QWidget 如何获得“整个”父级?的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5 - 在 QMainMenu 中,如何使 QWidget 成为父级(暂时)?

创建 QWidget 宽度 HWND 父级

由父级绘制 QWidget

强制 QObject 作为 QWidget 的父级有啥后果?

QWidget 失去了它的父级

如何在其父项下隐藏 QWidget?