C ++/Qt从qt中的另一个类访问ui的正确方法//已编辑 [英] C++ /Qt Proper way to access ui from another class in qt //Edited

查看:197
本文介绍了C ++/Qt从qt中的另一个类访问ui的正确方法//已编辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to access the ui member which is private in the MainWindow class.

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

I would like to update a lineEdit (Xvaldisp) when I release the mousebutton (with the amount the mouse moved)from a gl widget.

在四处搜索之后,我发现我需要在mainwindow中创建一个函数/方法然后通过我的GLWidget指向Mainwindow的指针对其进行访问

After searching a bit around I found that I need to create a function/Method in mainwindow then access it through a pointer to Mainwindow from my GLWidget

问题:

lineEdit保持空白,应该对其进行更新的method(displaymessage())被调用.

The lineEdit remains blank, The method( displaymessage() ) that should update it seems to get called.

要检查是否已创建一个字符串(str)以查看是否调用了displaymessage,请在调用displaymessage()时使用新值更新此字符串.

To check that I've created a string(str) to see if displaymessage was getting called, this string gets updated with a new value when displaymessage() gets called.

在displaymessage()下面的on_Button_clicked()方法还可以在单​​击按钮时更新相同的lineEdit,并且效果很好它显示str的内容

The on_Button_clicked() method below displaymessage() also updates the same lineEdit when a pushbutton is clicked and works just fine it displays the content of 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

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

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){


}

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);



    }

推荐答案

问题的根源在于您似乎误解了指针的概念.具体来说,调用 new 并不是唯一获得指针的方法-指针只是一个变量,该变量保存某个对象(或函数)的地址. new 运算符返回指向动态分配对象的指针,但是还有其他方法,至少有三种与您相关:
1)让别人给你一个指针,例如作为函数参数;
2)使用& 获取对象的地址.
3)使用 this 获取当前正在使用的对象的指针.

The root of your problem is that you seem to be misunderstanding the concept of pointers. Specifically, calling new is not the only way to obtain a pointer - a pointer is just a variable that holds the address of some object (or function). The new operator returns a pointer to a dynamically-allocated object, but there are other ways too, at least three of which are relevant to you:
1) Have someone else give you a pointer, for example as a function parameter;
2) Use & to take the address of an object.
3) Use this to get a pointer to the object you are currently working with.

现在我们已经解决了这个问题,请看一下您的代码. MainWindow 有两个插槽:

Now that we have that out of the way, take a look at your code. MainWindow has two slots:

class MainWindow : public QMainWindow {
    Q_OBJECT
    ...
public slots:
   void on_Button_clicked();
   void displayMessage();

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

Slots are member functions - they are called on an object.

创建类型为 MainWindow 的对象时,将自动连接 MainWindow 对象的 on_Button_clicked 插槽 Button clicked 信号(通过元对象编译器,这是Qt特定的事情,因为您使用的是特定的命名约定).

When you create an object of type MainWindow, the on_Button_clicked slot of your MainWindow object is automatically connected to the clicked signal of Button (via the meta-object compiler, a Qt-specific thing, because of the particular naming convention that you used).

另一个发生了什么?这是您的代码:

What happens to the other one? Here's your code:

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

您将创建一个 new 对象,并调用 its ,而不是连接到原始 MainWindow 对象的插槽.em>函数,并立即销毁它.因此,虽然确实调用了 slot ,但实际上并没有在您的gui对象上调用它.

Rather than connecting to the slot of the original MainWindow object, you are creating a new object, calling its function, and promptly destroying it. So, while the slot does get called, it doesn't get called on the object that is actually your gui.

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

This is happening because you figured you needed a pointer to a MainWindow object, and used new to get one. The problem is, that pointer didn't point to the object you actually care about (i.e. your actual gui).

一个(不确定的)解决方案是不创建新的MainWindow ;而是将原始 MainWindow 的地址传递给小部件,并在 connect 语句中使用该地址(指针).

One (inelegant) solution is to not create a new MainWindow; instead, pass the address of the original MainWindow to the widget, and use that address (pointer) in the connect statement.

更好的解决方案是跳过所有这些内容,并按其预期的方式使用信号和插槽,以使各个小部件不必了解与它们连接的对象有关的任何信息.

The much better solution is to skip all that stuff and use signals and slots the way they were intended, so that individual widgets don't have to know anything about the objects they are being connected to.

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

Change your MainWindow constructor to the following:

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

}

并除去 GLWidget :: displayMessage 中的 emit 语句以外的所有内容.

and get rid of everything but the emit statement inside GLWidget::displayMessage.

这篇关于C ++/Qt从qt中的另一个类访问ui的正确方法//已编辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆