Qt connect(*sender, *signal, *receiver, *method) 不调用槽

Qt connect(*sender, *signal, *receiver, *method) doesn't call slots

我对 Qt 和 C++ 都很陌生。我试着做了一点 Celsius/Fahrenheit 转换器。在 UI 上,我使用 QDial 和 QLCDNumber 分别更改和显示温度。 不幸的是,只有 "standard connect" 有效:

connect(ui->celsiusDial, SIGNAL(valueChanged(int)), ui->celsiusLcd,SLOT(display(int)));

旋转表盘会导致 LCD-Widget 发生变化,但其他任何方法都不起作用(请参阅 [=37= 中的 connect(...) 调用].

该项目有一个名为 Dialog 的 QWidget,它调用 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;
}

这是我的 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;
}

最后我的 UI 看起来像这样: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>

在此先感谢,我真的不知道错误来自哪里。

问题是 tempConverterObject 变量仅存在于构造函数中,因为它是在该上下文中创建的,即它是一个局部变量,并且在执行该函数时从内存中删除。解决方案是将该变量转换为 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)));

}