如何使较低的 class 调用其父级的方法?
How to make a lower class call a method of its parent?
我已经关注了这个教程Qt Creator + OpenGL,一切都很顺利。
我在 Quit
按钮上添加了一个 QPlainTextEdit
,我想让 GLWidget
将信息发回给 MainWindow
。
如何让 GLWidget
调用 MainWindow
的函数?
这是一些代码:
// GLWidget.h
class GLWidget: public QGLWidget
{
Q_OBJECT // <-----
public:
GLWidget(QWidget* parent = 0);
QWidget* parentObject;
void writeText( QString );
void (*p)(QString) = NULL;
protected:
virtual void initializeGL();
virtual void paintGL();
virtual void resizeGL(int w, int h);
private:
QTimer timer;
signals:
//void writeText( QString );
void dataReady(QString data); // <------------------
};
// GLWidget.cpp
GLWidget::GLWidget(QWidget* parent) : QGLWidget() /7 <---- new error
{
connect(&timer, SIGNAL(timeout()), this, SLOT(updateGL()));
timer.start(16);
QMessageBox msgBox;
msgBox.setText(typeid(parent).name());
msgBox.exec();
//p = parent->
//parentObject->
//parent->
//parent->
//this->parentObject = parent;
}
void GLWidget::initializeGL(){
//emit GLWidget::dataReady("myData"); //<--------- error
emit this->dataReady("Joe");//<--------- same as above
glClearColor(0.2, 0.2, 0.2, 1);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
}
// MainWindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void print(QString text);
private slots:
void on_plainTextEdit_textChanged();
void foo(QString data); // <----------------------
}
// mainwindow.cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->widget->p = &MainWindow::print; // error, how to asign pointer?
}
void MainWindow::print(QString text){
ui->plainTextEdit->setPlainText(text);
}
void MainWindow::foo(QString data) { // <---------
QMessageBox msgBox;
msgBox.setText("hi, there");
msgBox.exec();
// Do something with the data
ui->plainTextEdit->setPlainText(data);
}
错误:
- 对“GLWidget 的 vtable”的未定义引用
- 对“GLWidget::dataReady(QString)”的未定义引用
这是您的直接问题的答案,How to make a lower class exploit a function in it's parent?:
所有 QObject
子 class 都持有对其 parent object 的引用,可通过 parent()
方法访问。
- 包括 parent 的 class 的 header,例如
Foo.h
- 调用
parent()
方法获取指向 object 的 parent 的指针
- 检查指针是否有效(不是
nullptr
)
- 将指针指向 parent 的 class,例如
Foo
- 调用所需的方法,例如
foo
在代码中它看起来像这样:
#include "Foo.h"
...
if (parent())
static_cast<Foo *>(parent())->foo();
也就是说,这会在 parent 和 child 之间造成紧密耦合,我强烈建议尽可能避免这样做。在您的情况下,使用信号和插槽将数据从 child 传送到 parent:
会好得多
- 在child中定义一个信号,例如
dataReady(DataType data)
- 在 parent 中,当您创建 child 时,将此信号连接到将使用数据的方法,例如
foo
- 在child、
emit
信号中,每当你想打电话foo
在代码中它看起来像这样:
Child.h
...
signals:
void dataReady(DataType data);
...
Child.cpp
...
// I want to call foo
emt dataReady(myData);
...
Parent.h
...
private slots:
void foo(DataType data);
...
Parent.cpp
...
//somewhere
auto *child = new Child(...);
connect(child, &Child::dataReady, this, &Parent::foo);
...
void Parent::foo(DataType data) {
// Do something with the data
...
}
...
这最初需要更多的工作,但在 long-term 中会好得多。
我已经关注了这个教程Qt Creator + OpenGL,一切都很顺利。
我在 Quit
按钮上添加了一个 QPlainTextEdit
,我想让 GLWidget
将信息发回给 MainWindow
。
如何让 GLWidget
调用 MainWindow
的函数?
这是一些代码:
// GLWidget.h
class GLWidget: public QGLWidget
{
Q_OBJECT // <-----
public:
GLWidget(QWidget* parent = 0);
QWidget* parentObject;
void writeText( QString );
void (*p)(QString) = NULL;
protected:
virtual void initializeGL();
virtual void paintGL();
virtual void resizeGL(int w, int h);
private:
QTimer timer;
signals:
//void writeText( QString );
void dataReady(QString data); // <------------------
};
// GLWidget.cpp
GLWidget::GLWidget(QWidget* parent) : QGLWidget() /7 <---- new error
{
connect(&timer, SIGNAL(timeout()), this, SLOT(updateGL()));
timer.start(16);
QMessageBox msgBox;
msgBox.setText(typeid(parent).name());
msgBox.exec();
//p = parent->
//parentObject->
//parent->
//parent->
//this->parentObject = parent;
}
void GLWidget::initializeGL(){
//emit GLWidget::dataReady("myData"); //<--------- error
emit this->dataReady("Joe");//<--------- same as above
glClearColor(0.2, 0.2, 0.2, 1);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
}
// MainWindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void print(QString text);
private slots:
void on_plainTextEdit_textChanged();
void foo(QString data); // <----------------------
}
// mainwindow.cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->widget->p = &MainWindow::print; // error, how to asign pointer?
}
void MainWindow::print(QString text){
ui->plainTextEdit->setPlainText(text);
}
void MainWindow::foo(QString data) { // <---------
QMessageBox msgBox;
msgBox.setText("hi, there");
msgBox.exec();
// Do something with the data
ui->plainTextEdit->setPlainText(data);
}
错误:
- 对“GLWidget 的 vtable”的未定义引用
- 对“GLWidget::dataReady(QString)”的未定义引用
这是您的直接问题的答案,How to make a lower class exploit a function in it's parent?:
所有 QObject
子 class 都持有对其 parent object 的引用,可通过 parent()
方法访问。
- 包括 parent 的 class 的 header,例如
Foo.h
- 调用
parent()
方法获取指向 object 的 parent 的指针
- 检查指针是否有效(不是
nullptr
) - 将指针指向 parent 的 class,例如
Foo
- 调用所需的方法,例如
foo
在代码中它看起来像这样:
#include "Foo.h"
...
if (parent())
static_cast<Foo *>(parent())->foo();
也就是说,这会在 parent 和 child 之间造成紧密耦合,我强烈建议尽可能避免这样做。在您的情况下,使用信号和插槽将数据从 child 传送到 parent:
会好得多- 在child中定义一个信号,例如
dataReady(DataType data)
- 在 parent 中,当您创建 child 时,将此信号连接到将使用数据的方法,例如
foo
- 在child、
emit
信号中,每当你想打电话foo
在代码中它看起来像这样:
Child.h
...
signals:
void dataReady(DataType data);
...
Child.cpp
...
// I want to call foo
emt dataReady(myData);
...
Parent.h
...
private slots:
void foo(DataType data);
...
Parent.cpp
...
//somewhere
auto *child = new Child(...);
connect(child, &Child::dataReady, this, &Parent::foo);
...
void Parent::foo(DataType data) {
// Do something with the data
...
}
...
这最初需要更多的工作,但在 long-term 中会好得多。