C++/Qt在qt中从另一个类访问ui的正确方法//编辑

use*_*191 3 c++ qt

我正在尝试访问MainWindow类中私有的ui成员.

我想从gl小部件释放鼠标按钮(鼠标移动量)时更新lineEdit(Xvaldisp).

在搜索了一下之后我发现我需要在mainwindow中创建一个函数/ Method然后通过我的GLWidget中指向Mainwindow的指针来访问它

问题:

lineEdit保持空白,应该更新它的方法(displaymessage())似乎被调用.

要检查我是否已创建一个字符串(str)以查看是否正在调用displaymessage,当调用displaymessage()时,此字符串将使用新值进行更新.

displaymessage()下面的on_Button_clicked()方法也会在单击按钮时更新相同的lineEdit并且工作得很好它会显示str的内容

这是我的代码:

glwidget.h

#ifndef GLWIDGET_H
#define GLWIDGET_H

#include <QGLWidget>
#include <QTimer>
#include <QMouseEvent>
#include "mainwindow.h"
#include <QObject>
#include <QLineEdit>



class GLWidget : public QGLWidget
{
Q_OBJECT


public:

    explicit GLWidget(QWidget *parent = 0);


void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);

void initializeGL();
void paintGL();
void resizeGL(int w, int h);

private:

    QTimer timer;

QPoint pointMpressed;
QPoint diff;


protected:


signals:
    void valueCh();     


    };

    #endif // GLWIDGET_H
Run Code Online (Sandbox Code Playgroud)

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include <QObject>

#include "glwidget.h"

namespace Ui {
    class MainWindow;
}


class MainWindow : public QMainWindow {
    Q_OBJECT


public:
    MainWindow(QWidget *parent = 0);
   ~MainWindow();




public slots:


   void on_Button_clicked();
   void displayMessage();


protected:
    void changeEvent(QEvent *e);


private:
    Ui::MainWindow *ui;

};




#endif // MAINWINDOW_H
Run Code Online (Sandbox Code Playgroud)

glwidget.cpp.

#include "glwidget.h"
#include <GL/glut.h>



GLWidget::GLWidget(QWidget *parent) :
    QGLWidget(parent)
{

    connect (&timer,SIGNAL(timeout()),this,SLOT(updateGL()));
    timer.start(16);


}

void GLWidget::mousePressEvent(QMouseEvent *e){

    pointMpressed=e->pos();


}

void GLWidget::mouseReleaseEvent(QMouseEvent *e){

    diff=(e->pos())- pointMpressed ; //calculate position difference between click  and release


    MainWindow *mwd;

        mwd=  new MainWindow;


    //  mwd->displayMessage();   //tried this first then with signals and slots below same result

        QObject::connect(this, SIGNAL(valueCh()), mwd ,SLOT(displayMessage()) );

    emit valueCh();


   delete mwd;


    }


void GLWidget::initializeGL(){


}



void GLWidget::resizeGL(int w, int h){


}
Run Code Online (Sandbox Code Playgroud)

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "glwidget.h"



QString str="none activated";  //I used this string to check if the methods were getting called




MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

}



MainWindow::~MainWindow()
{

    delete ui;

}




void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}





 void MainWindow::displayMessage(){   //this method should  update the lineEdit (Xvaldisp)  the lineEdit however remains blank  but str gets updated


     ui->Xvaldisp->setText(str);

     str ="displayMessage hs rn";   //displaymessage has run

 }





    void MainWindow::on_Button_clicked(){ // this is a pushbutton(Button) that once pushed  also updates the same lineEdit(Xvaldisp)  this works just fine  If I clicked and released the mouse before on the GLWidget it would show the by displaymessage() updated string else it would be the orginal value   

        ui->Xvaldisp->setText(str);



    }
Run Code Online (Sandbox Code Playgroud)

tmp*_*rce 6

问题的根源在于你似乎误解了指针的概念.具体而言,呼叫new获得的指针的唯一方法-一个指针仅仅是持有一些物体(或功能)的地址的变量.该new运营商返回一个指向一个动态分配的对象,但也有其他的方式也一样,至少三个是与你有关的:
1)让别人给你一个指针,例如作为函数参数;
2)&用于获取对象的地址.
3)this用于获取指向当前正在使用的对象的指针.

现在我们已经完成了这项工作,请查看您的代码. MainWindow有两个插槽:

class MainWindow : public QMainWindow {
    Q_OBJECT
    ...
public slots:
   void on_Button_clicked();
   void displayMessage();
Run Code Online (Sandbox Code Playgroud)

插槽是成员函数 - 它们在对象调用.

当您创建类型的对象MainWindow,该on_Button_clicked你的MainWindow对象会自动连接到clicked的信号Button(通过元对象编译器,一个特定的Qt的事情,因为你使用的特定命名约定).

另一个会发生什么?这是你的代码:

void GLWidget::mouseReleaseEvent(QMouseEvent *e){  
     MainWindow *mwd;  
     mwd=  new MainWindow;  
     QObject::connect(this, SIGNAL(valueCh()), mwd ,SLOT(displayMessage()) );  
     emit valueCh();  
     delete mwd;  
}
Run Code Online (Sandbox Code Playgroud)

您正在创建一个对象,调用功能并立即销毁它,而不是连接到原始MainWindow对象的插槽.因此,当被调用时,它不会被调用实际上是你的gui的对象.slot

发生这种情况是因为您认为您需要一个指向MainWindow对象的指针,并且用于new获取一个.问题是,指针没有指向你真正关心的对象(即你的实际对象gui).

一个(不优雅)的解决方案是不创造new MainWindow; 相反,将原始地址传递MainWindow给窗口小部件,并在connect语句中使用该地址(指针).

更好的解决方案是跳过所有内容并按照预期的方式使用信号和插槽,这样各个小部件就不必了解它们所连接的对象.

MainWindow构造函数更改为以下内容:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->glWidget, SIGNAL(mouseReleaseEvent()),this,SLOT(displayMessage()));

}
Run Code Online (Sandbox Code Playgroud)

除了emit里面的陈述,除去一切GLWidget::displayMessage.