Weird problem, with MainWindow class variables.
-
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.
-
This is my implementation, for example:
mainwindow.h
@class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
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_OBJECTpublic:
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();
}@
-
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();
@
-
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.
-
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.
-
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_OBJECTpublic:
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_OBJECTpublic: 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;
}
@ -
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(); }
@
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.
-
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_Hclass 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;
...
}
@