Ui doesn't get updated when accessed from other class through method



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

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

    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

    The problem:

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

    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.

    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

    Here's my code:

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

    @

    Been bugging me for days now


  • Moderators

    You are not showing all the code, but this is definitely in wrong order:
    @
    ui->Xvaldisp->setText(str);
    str ="displayMessage hs rn";
    @

    You are setting the string on the QLineEdit first and then setting it's value! Since ::setText() copies the string, your update will not be shown. You need to set your string's value first, and then use setText().



  • [quote author="sierdzio" date="1373205818"]You are not showing all the code, but this is definitely in wrong order:
    @
    ui->Xvaldisp->setText(str);
    str ="displayMessage hs rn";
    @

    You are setting the string on the QLineEdit first and then setting it's value! Since ::setText() copies the string, your update will not be shown. You need to set your string's value first, and then use setText().[/quote]

    No the order is ok this way

    my problem is that displaymessage doesn't display anything

    the value is already set when I declared te string (mainwindow.cpp line 7) to "none activated"
    That gets displayed if I click on Button which calls on_Button_clicked() and displaymessage hasn't executed.

    My problem is that displaymessage doesn't update the lineEdit it remains blank.

    If it would show 'none activated' that would be perfectly fine
    I just want it to show something other than remaining blank.
    @
    ui->Xvaldisp->setText(str); @
    in displaymessage() doesn't seem to do anything

    @void GLWidget::mouseReleaseEvent(QMouseEvent *e){

        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;
    
        }@
    

    This is in GlWidget and should call displaymessage() in mainwindow when I release the mouse

    displaymessage() should then update the lineEdit to 'none activated' the first time I click and release the mouse and to 'displaymessage has rn' the second time but that doesn't happen

    displaymessage() updates the string but doesn't update the lineEdit

    What hapens is that the lineEdit remains blank until I push a pushbutton that calls on_Button_clicked() which then displays the value of str

    now if I hadn't clicked the mouse and released it and I then push the button the lineEdit would get updated by on_button_clicked to 'none activated' which means displaymessage hasn't updated the value

    If I had it would show 'displaymessage hs run'
    This indicates that displaymessage gets executed but fails to update te lineEdit for whatever reason

    My goal is that displaymessage just displays the content of str in a lineEdit just like on_Button_clicked does when I push Button

    That doesn't happen
    displaymessage gets executed but te lineEdit remains blank.
    as if it never executed

    my goal was to get the amount the mouse moved and show it in two lineEdits one for X and one for Y
    displaymessage however fails to display anything

    This is all te code I have atm except for the .ui file and .pro file

    this is what the ui looks like atm
    !http://s22.postimg.org/ulj52kx41/Screenshot_mainwindow_ui_qopengltrial_Qt_Cre.png()!


  • Lifetime Qt Champion

    Hi,

    You are creating a new MainWindow each time you call mouseReleaseEvent and deleting it at the end of the function.

    So in short you are expecting to see an update on a widget that is never shown and destroyed before it could be shown.

    You need to refactor your application logic: only emit the data from the mouseReleaseEvent and create your MainWindow somewhere more appropriated.

    Hope it helps



  • [quote author="SGaist" date="1373227553"]Hi,

    You are creating a new MainWindow each time you call mouseReleaseEvent and deleting it at the end of the function.

    So in short you are expecting to see an update on a widget that is never shown and destroyed before it could be shown.

    You need to refactor your application logic: only emit the data from the mouseReleaseEvent and create your MainWindow somewhere more appropriated.

    Hope it helps
    [/quote]

    My problem seems to be something like that ..

    I asked on StackExchange and got an answer *credits to tmpearce *

    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.

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

    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.

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

    }
    @

    This sounds pretty sound

    I'll try to print the adresses from both the new MainWindow and the orginal one to see if they match


  • Lifetime Qt Champion

    You do know that mouseReleaseEvent is not a signal ? Unless of course you have added a signal with that name (which is a bad idea, the name is confusing)



  • [quote author="SGaist" date="1373312713"]You do know that mouseReleaseEvent is not a signal ? Unless of course you have added a signal with that name (which is a bad idea, the name is confusing)[/quote]

    Yes I had to change that.

    I connected a signal called valueCh()
    @ connect(ui->glWidget, SIGNAL(valueCh()),this,SLOT(displayMessage()));@

    Which works


  • Lifetime Qt Champion

    Good !

    If this solves your problem, you can update the thread's title prepending solved to it.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.