【问题标题】:C++ /Qt Proper way to access ui from another class in qt //EditedC++ /Qt 在 qt 中从另一个类访问 ui 的正确方法 //Edited
【发布时间】:2013-07-02 21:34:01
【问题描述】:

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

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

经过一番搜索,我发现我需要在主窗口中创建一个函数/方法 然后通过我的 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

ma​​inwindow.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){


}

ma​​inwindow.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);



    }

【问题讨论】:

  • 已初始化 mwd。从你的代码看来不是。
  • 您需要将指向现有 MainWindow 的指针传递给 GLWidget
  • 感谢 cmets 我该怎么做?真的不熟悉cpp类需要尽快阅读
  • 您可能会遇到上述初始化问题...但是您还应该考虑将signalGLWidget 连接到MainWindow 中的slot,而不是传递指针.

标签: c++ qt


【解决方案1】:

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

既然我们已经解决了这个问题,请查看您的代码。 MainWindow 有两个插槽:

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

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

当您创建 MainWindow 类型的对象时,on_Button_clicked 插槽 MainWindow 对象 会自动连接到 Buttonclicked 信号(通过元对象编译器,一个特定于 Qt 的东西,因为您使用了特定的命名约定)。

另一个人会怎样?这是你的代码:

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

不是连接到原始MainWindow对象的槽,而是创建一个new对象,调用its函数,并且迅速摧毁它。所以,虽然 slot 确实被调用了,但它并没有在实际上是你的 gui 的对象上被调用。

发生这种情况是因为您认为需要一个指向 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()));

}

并摆脱除GLWidget::displayMessage 中的emit 语句之外的所有内容。

【讨论】:

  • 谢谢我已经怀疑我没有得到我原来的MainWindow的地址我仍然不太了解OOP的概念
  • 这有点含糊,但也许我会在几年内到达那里, SIGNAL(mouseReleaseEvent()),this,SLOT(displayMessage()));` 我使用了`connect(ui->glWidget, SIGNAL(valueCh()),this,SLOT(displayMessage()));` 并发出@ 987654344@ 现在效果很好,我很高兴 :)
猜你喜欢
  • 2021-08-10
  • 1970-01-01
  • 1970-01-01
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多