I'm very new to Qt and also to c++. I tried to do a little Celsius/Fahrenheit converter. On the UI I use QDial and QLCDNumber to respectively change and show the temperature. Unfortunately only the "standard connect" works:
connect(ui->celsiusDial, SIGNAL(valueChanged(int)), ui->celsiusLcd,SLOT(display(int)));
Spinning the dial leads to change on the LCD-Widget but anything else doesn't work (see the connect(...) calls in dialog.cpp.
The project have a QWidget with the name Dialog that calls the tempconverter.cpp class. Dialog.cpp:
#include "dialog.h"
#include "ui_dialog.h"
#include "tempconverter.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
TempConverter tempConverterObject(0, this);
TempConverter * tempConverter = &tempConverterObject;
connect(ui->celsiusDial, SIGNAL(valueChanged(int)), tempConverter, SLOT(setTempCelsius(int)));
connect(ui->celsiusDial, SIGNAL(valueChanged(int)), ui->celsiusLcd, SLOT(display(int)));
connect(tempConverter, SIGNAL(tempCelsiusChanged(int)), ui->celsiusDial, SLOT(setValue(int)));
connect(ui->fahrenheitDial, SIGNAL(valueChanged(int)), tempConverter, SLOT(setTempFahrenheit(int)));
connect(ui->fahrenheitDial, SIGNAL(valueChanged(int)), ui->fahrenheitLcd, SLOT(display(int)));
connect(tempConverter, SIGNAL(tempFahrenheitChanged(int)), ui->fahrenheitDial, SLOT(setValue(int)));
}
Dialog::~Dialog()
{
delete ui;
}
Here's my TempConverter-class:
Header: tempconverter.h
#ifndef TEMPCONVERTER_H
#define TEMPCONVERTER_H
#include <QObject>
class TempConverter : public QObject
{
Q_OBJECT
public:
TempConverter(int tempCelsius, QObject *parent = 0);
int tempCelsius() const; // const is signature for getters!(that's why they are blue!)
int tempFahrenheit() const;
public slots:
void setTempCelsius(int);
void setTempFahrenheit(int);
signals:
void tempCelsiusChanged(int); // Signals are only declared not "implemented", they are emitted when a event occurs
void tempFahrenheitChanged(int); // Signals are only declared not "implemented", they are emitted when a event occurs
private:
int m_tempCelsius; // internal representation of celsiusTemp <=> Java Attribute
};
#endif // TEMPCONVERTER_H
Class: tempconverter.cpp
#include "tempconverter.h"
#include <QDebug>
TempConverter::TempConverter(int tempCelsius, QObject *parent) : QObject(parent) // this is the constructor
{
qDebug("default constructor");
m_tempCelsius = tempCelsius;
}
void TempConverter::setTempCelsius(int tempCelsius)
{
//qDebug("setTempCelsius");
if(m_tempCelsius == tempCelsius)
return;
m_tempCelsius = tempCelsius;
emit tempCelsiusChanged(m_tempCelsius);
emit tempFahrenheitChanged(tempFahrenheit());
}
void TempConverter::setTempFahrenheit(int tempFahrenheit){
qDebug("setTempFahrenheit");
int tempCelsius = (5.0/9.0)*(tempFahrenheit-32);
setTempCelsius(tempCelsius);
qDebug("setTempFahrenheit");
}
int TempConverter::tempCelsius() const{
return m_tempCelsius;
}
int TempConverter::tempFahrenheit() const{
return (m_tempCelsius*2)+30;
}
And finally my UI looks like this: dialog.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>30</x>
<y>40</y>
<width>331</width>
<height>231</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Celsius</string>
</property>
<widget class="QDial" name="celsiusDial">
<property name="geometry">
<rect>
<x>0</x>
<y>30</y>
<width>161</width>
<height>141</height>
</rect>
</property>
</widget>
<widget class="QLCDNumber" name="celsiusLcd">
<property name="geometry">
<rect>
<x>3</x>
<y>172</y>
<width>161</width>
<height>41</height>
</rect>
</property>
</widget>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Fahrenheit</string>
</property>
<widget class="QDial" name="fahrenheitDial">
<property name="geometry">
<rect>
<x>0</x>
<y>20</y>
<width>161</width>
<height>141</height>
</rect>
</property>
</widget>
<widget class="QLCDNumber" name="fahrenheitLcd">
<property name="geometry">
<rect>
<x>0</x>
<y>170</y>
<width>161</width>
<height>41</height>
</rect>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
Thanks in advance, I really have no clue where the error is coming from.
The problem is that the tempConverterObject
variable only exists in the constructor since it has been created in that context, ie it is a local variable and it is removed from memory when that function is executed. The solution is to convert that variable to a member of the class:
*.h
private:
Ui::Dialog *ui;
TempConverter *tempConverter;
*.cpp
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
tempConverter = new TempConverter(0, this);
connect(ui->celsiusDial, SIGNAL(valueChanged(int)), tempConverter, SLOT(setTempCelsius(int)));
connect(ui->celsiusDial, SIGNAL(valueChanged(int)), ui->celsiusLcd, SLOT(display(int)));
connect(tempConverter, SIGNAL(tempCelsiusChanged(int)), ui->celsiusDial, SLOT(setValue(int)));
connect(ui->fahrenheitDial, SIGNAL(valueChanged(int)), tempConverter, SLOT(setTempFahrenheit(int)));
connect(ui->fahrenheitDial, SIGNAL(valueChanged(int)), ui->fahrenheitLcd, SLOT(display(int)));
connect(tempConverter, SIGNAL(tempFahrenheitChanged(int)), ui->fahrenheitDial, SLOT(setValue(int)));
}