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.
QtWS25 Last Chance

Weird problem, with MainWindow class variables.

Scheduled Pinned Locked Moved General and Desktop
18 Posts 4 Posters 3.3k Views
  • 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