Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Weird problem, with MainWindow class variables.
Forum Updated to NodeBB v4.3 + New Features

Weird problem, with MainWindow class variables.

Scheduled Pinned Locked Moved General and Desktop
18 Posts 4 Posters 3.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    AndreasA9
    wrote on last edited by
    #1

    So i have two separate classes. MainWindow and my own class. When i try to access MainWindow variables from my own class, i will face up some problem. Either i have method, which returns private variable from MainWindow to my own class or i try to access it when variable is public. Problem is that, the return i get, is very unrealistic. I have two variables in MainWindow class, which ones are equal to two QSlider value.

    Here are defined variables at MainWindow class

    @
    private:
    int imageWidth;
    int imageHeight;
    @

    I have 2 slots, which act, when QSliders values are changed

    @void MainWindow::on_WidthSlider_valueChanged(int value)
    {
    imageWidth = value;
    QString valueString = QString::number(value);
    ui->WidthLabel->setText(valueString);
    }

    void MainWindow::on_HeightSlider_valueChanged(int value)
    {
    imageHeight = value;
    QString valueString = QString::number(value);
    ui->HeightLabel->setText(valueString);
    }@

    Here are two methods, which one should "return" these variable values.

    @
    void MainWindow::GetImageHeight(int &height) {height = imageHeight;}

    void MainWindow::GetImageWidth(int &width) {width = imageWidth; }@

    And here is the part, how i try to access them.

    @
    MainWindow mw;
    int width, height;

    mw.GetImageHeight(height);
    mw.GetImageWidth(width);
    

    @

    PROBLEM is that, i always get wrong results. If MainWindow instance are defined as variable, then methods return 0. If they are defined as pointers, then they return -842150451. I cannot find solution to my problem, i hope someone can help me.

    1 Reply Last reply
    0
    • V Offline
      V Offline
      Vovasty
      wrote on last edited by
      #2

      Do you connected QSlider::valueChanged(int) signal to your MainWindow::on_WidthSlider_valueChanged(int) and MainWindow::on_HeightSlider_valueChanged(int) slots?

      1 Reply Last reply
      0
      • A Offline
        A Offline
        AndreasA9
        wrote on last edited by
        #3

        Yeah, i also debugged that, is the on_HeightSlider_valueChanged(int) parameter value correct and yes it is.

        1 Reply Last reply
        0
        • V Offline
          V Offline
          Vovasty
          wrote on last edited by
          #4

          What relations between your own class and MainWindow? May be you could create signals-slots communications between both classes.

          1 Reply Last reply
          0
          • V Offline
            V Offline
            Vovasty
            wrote on last edited by
            #5

            This is my implementation, for example:

            mainwindow.h
            @class MainWindow : public QMainWindow
            {
            Q_OBJECT

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

            signals:
            void heightValueChanged(int value);
            void widthValueChanged(int value);

            private slots:
            void widthSliderChanged(int value);
            void heightSliderChanged(int value);

            private:
            Ui::MainWindow *ui;

            int _imageHeight;
            int _imageWidth;
            

            };@

            mainwindow.cpp
            @MainWindow::MainWindow(QWidget *parent) :
            QMainWindow(parent),
            ui(new Ui::MainWindow),
            _imageHeight(0),
            _imageWidth(0)
            {
            ui->setupUi(this);

            connect(ui->heightlSlider, SIGNAL(valueChanged(int)), this, SLOT(heightSliderChanged(int)));
            connect(ui->widthSlider, SIGNAL(valueChanged(int)), this, SLOT(widthSliderChanged(int)));
            

            }

            MainWindow::~MainWindow()
            {
            delete ui;
            }

            void MainWindow::widthSliderChanged(int value)
            {
            if (_imageWidth == value)
            return;

            _imageWidth = value;
            emit widthValueChanged(_imageWidth);
            

            }

            void MainWindow::heightSliderChanged(int value)
            {
            if (_imageHeight == value)
            return;

            _imageHeight = value;
            emit heightValueChanged(_imageHeight);
            

            }@

            ownclass.h
            @class Own : public QWidget
            {
            Q_OBJECT

            public:
            Own(QWidget *parent = 0);

            public slots:
            void imageHeight(int value);
            void imageWidth(int value);
            };
            @

            ownclass.cpp
            @Own::Own(QWidget *parent) :
            QWidget(parent)
            {

            }

            void Own::imageHeight(int value)
            {
            qDebug() << QString::number(value);
            }

            void Own::imageWidth(int value)
            {
            qDebug() << QString::number(value);
            }@

            main.cpp
            @int main(int argc, char *argv[])
            {
            QApplication a(argc, argv);
            MainWindow w;
            Own own;

            QObject::connect(&w, SIGNAL(heightValueChanged(int)), &own, SLOT(imageHeight(int)));
            QObject::connect(&w, SIGNAL(widthValueChanged(int)), &own, SLOT(imageWidth(int)));
            
            w.show();
            
            return a.exec&#40;&#41;;
            

            }@

            1 Reply Last reply
            0
            • A Offline
              A Offline
              AndreasA9
              wrote on last edited by
              #6

              QSlider valueChanged are already connected to on_WidthSlider_valueChanged(int value) and on_HeightSlider_valueChanged(int value)

              1 Reply Last reply
              0
              • R Offline
                R Offline
                Rondog
                wrote on last edited by
                #7

                I ran into something similar to this recently when trying to update a value by reference. In my case it was done this way for a very different reason but otherwise it was similar to what you are doing.

                I would suggest you re-write your access functions like this:

                @
                int MainWindow::GetImageHeight(void) {return imageHeight;}
                int MainWindow::GetImageWidth(void) {return imageWidth; }
                @

                You can use them like this:

                @
                MainWindow mw;
                int width, height;

                height = mw.GetImageHeight();
                width = mw.GetImageWidth();
                

                @

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  AndreasA9
                  wrote on last edited by
                  #8

                  I have already tried this.

                  1 Reply Last reply
                  0
                  • R Offline
                    R Offline
                    Rondog
                    wrote on last edited by
                    #9

                    In your code you have this:

                    @
                    QApplication a(argc, argv);
                    MainWindow w;
                    Own own;
                    ...
                    @

                    These exist only in main() which will run until a.exec() returns. For the classes 'w' and 'own' is there a pointer, or some other reference to these classes that you can use outside of main()?

                    For this code:

                    @
                    MainWindow mw;
                    int width, height;

                        height = mw.GetImageHeight();
                        width = mw.GetImageWidth();
                    

                    @

                    GetImageHeight() and GetImageWidth() should return zero or possibly some other random value as it is another, unrelated class.

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      AndreasA9
                      wrote on last edited by
                      #10

                      Sorry, i don't understand, what you are trying to say to me.

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        andreyc
                        wrote on last edited by
                        #11

                        In your example (below), are you trying to get width and height from MainWindow before app.exec() ?
                        @
                        MainWindow mw;
                        int width, height;

                            mw.GetImageHeight(height);
                            mw.GetImageWidth(width);
                        

                        @

                        If so then MainWindow::imageHeight and imageWidth are not initialized and you are getting whatever random numbers are there.

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          AndreasA9
                          wrote on last edited by
                          #12

                          No, im not trying to get them before app.exec()
                          getImageHeight and getImageWidth are exectued after i press a button on my form and long proccess is done with network communication is done

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            AndreasA9
                            wrote on last edited by
                            #13

                            I post my full source code here

                            mainwindow.h
                            @
                            #ifndef MAINWINDOW_H
                            #define MAINWINDOW_H

                            #include <QMainWindow>
                            #include "networking.h"
                            namespace Ui {
                            class MainWindow;
                            }

                            class MainWindow : public QMainWindow
                            {
                            Q_OBJECT

                            public:

                            explicit MainWindow(QWidget *parent = 0);
                            void GetImageHeight(int &height);
                            void GetImageWidth(int &width);
                            
                            ~MainWindow();
                            

                            private slots:

                            void on_pushButton_clicked();
                            void on_WidthSlider_valueChanged(int value);
                            void on_HeightSlider_valueChanged(int value);
                            

                            private:
                            int imageWidth;
                            int imageHeight;

                            QUrl q;
                            Ui::MainWindow *ui;
                            

                            };

                            #endif // MAINWINDOW_H

                            @

                            networking.h

                            @
                            #ifndef NETWORKING_H
                            #define NETWORKING_H

                            #include <QtNetwork/QNetworkAccessManager>
                            #include <QtNetwork/QNetworkRequest>
                            #include <QMessageBox>
                            #include "mainwindow.h"

                            class networking : public QObject
                            {
                            Q_OBJECT

                            public:
                                networking();
                            
                                void on_download_triggered(QUrl url);
                                bool IsNetworkAvailable();
                            
                            
                            private:
                                QNetworkAccessManager *manager = new QNetworkAccessManager(this);
                                void ProcessPicture(QImage *image);
                            

                            private slots:
                            void onNetworkReply(QNetworkReply* reply);

                            };

                            #endif // NETWORKING_H

                            @

                            mainwindow.cpp

                            @#include "mainwindow.h"
                            #include "ui_mainwindow.h"

                            MainWindow::MainWindow(QWidget *parent) :
                            QMainWindow(parent),
                            ui(new Ui::MainWindow)
                            {

                            ui->setupUi(this);
                            this->setFixedSize(378, 304);
                            

                            }

                            MainWindow::~MainWindow()
                            {
                            delete ui;
                            }

                            void MainWindow::on_pushButton_clicked()
                            {

                            if(ui->URLbox->text().isEmpty()) QMessageBox::information(0, "Warning", "No URL inserted!");
                            
                            else
                            {
                                networking *n = new networking();
                                q = ui->URLbox->text();
                                if(n->IsNetworkAvailable()) n->on_download_triggered(q);
                            }
                            

                            }

                            void MainWindow::GetImageHeight(int &height) {height = imageHeight;}

                            void MainWindow::GetImageWidth(int &width) {width = imageWidth; }

                            void MainWindow::on_WidthSlider_valueChanged(int value)
                            {
                            imageWidth = value;
                            QString valueString = QString::number(value);
                            ui->WidthLabel->setText(valueString);
                            }

                            void MainWindow::on_HeightSlider_valueChanged(int value)
                            {
                            imageHeight = value;
                            QString valueString = QString::number(value);
                            ui->HeightLabel->setText(valueString);
                            }

                            @

                            networking.cpp

                            @#include "networking.h"
                            #include <QtNetwork/QNetworkReply>
                            #include <QFileDialog>

                            networking::networking()
                            {
                            connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onNetworkReply(QNetworkReply*)));
                            }
                            void networking::on_download_triggered(QUrl url)
                            {
                            manager->get(QNetworkRequest(QUrl(url)));
                            }

                            void networking::ProcessPicture(QImage *image)
                            {
                            MainWindow *mw = new MainWindow();

                            int width, height;
                            
                            mw->GetImageHeight(height);
                            mw->GetImageWidth(width);
                            
                            
                            qDebug() << height;
                            qDebug() << width;
                            
                            QImage newimage = image->scaled(width, height, Qt::KeepAspectRatio);
                            QString path =  QFileDialog::getSaveFileName(0, tr("Save Image"), "C://", tr("Image Files (*.png *.jpg *.bmp)"));
                            
                            newimage.save(path);
                            

                            }

                            void networking::onNetworkReply(QNetworkReply* reply)
                            {
                            if(!reply->error())
                            {
                            QImage *img = new QImage();
                            img->loadFromData(reply->readAll());

                                if(img->isNull())
                                        QMessageBox::critical(0, "Error", "Inserted URL is not an image!");
                            
                                ProcessPicture(img);
                            
                            }
                            else
                            {
                                QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
                                int status = statusCode.toInt();
                            
                                qDebug() << status;
                            
                                switch(status)
                                {
                                    case 0:
                                    {
                                        QMessageBox::critical(0, "Error", "URL doesn't exist!");
                                        break;
                                    }
                                    case 404:
                                    {
                                        QMessageBox::critical(0, "Error", "404 not found!");
                                        break;
                                    }
                                }
                            }
                            

                            }

                            bool networking::IsNetworkAvailable()
                            {
                            QNetworkAccessManager m;
                            QNetworkReply *check = m.get(QNetworkRequest(QUrl("google.com")));
                            return (!check->error()) ? true : false;
                            }
                            @

                            1 Reply Last reply
                            0
                            • R Offline
                              R Offline
                              Rondog
                              wrote on last edited by
                              #14

                              I think this is your problem:

                              @
                              void networking::ProcessPicture(QImage *image)
                              {
                              MainWindow *mw = new MainWindow();

                              int width, height;
                              
                              mw->GetImageHeight(height);
                              mw->GetImageWidth(width);
                              
                              qDebug() << height;
                              qDebug() << width;
                              

                              ...
                              }
                              @

                              The class '*mw' is unrelated to the mw class created in main(). The member imageWidth and imageHeight are not updated in this version.

                              To verify this you could create a global pointer of the MainWindow class and see if this solves the problem:

                              @
                              MainWindow *g_mw;

                              int main(int argc, char *argv[])
                              {
                                  QApplication a(argc, argv);
                                  MainWindow w;
                                  Own own;
                              
                                  g_mw = &mw;
                              
                               
                                  QObject::connect(&w, SIGNAL(heightValueChanged(int)), &own, SLOT(imageHeight(int)));
                                  QObject::connect(&w, SIGNAL(widthValueChanged(int)), &own, SLOT(imageWidth(int)));
                               
                                  w.show();
                               
                                  return a.exec&#40;&#41;;
                              }
                              

                              @

                              and then in your network module

                              @
                              #include "networking.h"
                              #include <QtNetwork/QNetworkReply>
                              #include <QFileDialog>

                              extern MainWindow *g_mw;

                              networking::networking()
                              {
                              ...
                              }
                              ...
                              void networking::ProcessPicture(QImage *image)
                              {
                              // MainWindow *mw = new MainWindow();

                              int width, height;
                              
                              g_mw->GetImageHeight(height);
                              g_mw->GetImageWidth(width);
                              
                              
                              qDebug() << height;
                              qDebug() << width;
                              

                              ...
                              }
                              @

                              Note: I wouldn't use a global variable like this. You are better to pass a pointer (maybe as part of the constructor of your Networking class?). It is just a simple way to verify this is the problem without changing too much.

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                andreyc
                                wrote on last edited by
                                #15

                                Rondog is right. You are creating new MainWindow object and it is not related to your main MainWindow.

                                Another option to solve it would be to pass a MainWindow pointer to networking ctor and keep it there. Then in networking::ProcessPicture() use that pointer.
                                networking.h

                                @
                                #ifndef NETWORKING_H
                                #define NETWORKING_H

                                class MainWindow;
                                 
                                class networking : public QObject
                                {
                                

                                ...
                                public:
                                networking(MainWindow* mw);

                                ...
                                private:
                                MainWindow* m_mw;

                                };
                                #endif // NETWORKING_H
                                

                                @

                                networking.cpp
                                @
                                #include "networking.h"
                                #include "MainWindow.h"
                                #include <QtNetwork/QNetworkReply>
                                #include <QFileDialog>

                                networking::networking(MainWindow* mw) : m_mw(mw)
                                {
                                

                                ...
                                }

                                void networking::ProcessPicture(QImage *image)
                                {
                                // MainWindow *mw = new MainWindow();

                                int width, height;
                                
                                m_mw->GetImageHeight(height);
                                m_mw->GetImageWidth(width);
                                
                                
                                qDebug() << height;
                                qDebug() << width;
                                

                                ...
                                }
                                @

                                1 Reply Last reply
                                0
                                • A Offline
                                  A Offline
                                  AndreasA9
                                  wrote on last edited by
                                  #16

                                  Thanks, it worked! I didn't know, why i didn't realise fault myself. Quite logical. Thanks again!

                                  1 Reply Last reply
                                  0
                                  • A Offline
                                    A Offline
                                    AndreasA9
                                    wrote on last edited by
                                    #17

                                    One last question, why i had to write class MainWindow; to my networking.h file.

                                    1 Reply Last reply
                                    0
                                    • A Offline
                                      A Offline
                                      andreyc
                                      wrote on last edited by
                                      #18

                                      It is a forward declaration. Compiler needs to know that a type exists but does not need to know the details. It works with the pointers and the references. Helps to avoid including unneeded headers.

                                      1 Reply Last reply
                                      0

                                      • Login

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • Users
                                      • Groups
                                      • Search
                                      • Get Qt Extensions
                                      • Unsolved