我遵循了这个繁琐的Qt Creator + OpenGL,一切进展顺利。
我在QPlainTextEdit按钮的顶部添加了一个Quit,我希望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)'的引用
  • 最佳答案

    这是您眼中的问题的答案,即如何使低级类在其父级中利用某个函数?:
    所有QObject子类都拥有对其父对象的引用,可以通过 parent() 方法进行访问。

  • 包含 parent 类(class)的标题,例如Foo.h
  • 调用parent()方法以获得指向该对象的父
  • 的指针
  • 检查指针是否有效(不是nullptr)
  • 将指针转换为父级的类,例如Foo
  • 调用所需的方法,例如foo

  • 在代码中,它看起来像这样:
    #include "Foo.h"
    
    ...
    
    if (parent())
        static_cast<Foo *>(parent())->foo();
    
    话虽如此,这在 parent 与 child 之间造成了紧密的联系,我强烈建议避免这样做。在您的情况下,使用信号和插槽将数据从子级传递到父级会更好:
  • 在子级中定义信号,例如dataReady(DataType data)
  • 在父级中,当您创建子级时,将此信号连接到将使用数据的方法,例如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
        ...
    }
    ...
    
    最初需要做更多的工作,但从长远来看会更好。

    10-05 18:33