jmjiru
jmjiru

Reputation: 11

Qt3 vs Qt5 programming syntax

Hi I'm teaching myself Qt based on Qt 5.7.0 (MSVC 2013, 32 bit), Qt Creator 4.1.0 - community edition. I am using an book, "Programming with Qt, 2nd Edition" by Matthias Kalle Dalheimer which focuses on QT3. One of the exercises is to have a slider which uses the LCD number display. There are also two buttons (add, subtract) to change the slider and LCD display. I was not able to get the book code to work because there have been major syntax changes.

I was able to get my code to work using the Qt designer but I want to do it without that as well. How can I do that? I was thinking of using events but I couldn't figure out the syntax.

Here is the snippets from the book.

QObject::connect(decrement, SIGNAL(clicked()), myslider, SLOT(subtractStep()));
QObject::connect(increment, SIGNAL(clicked()), myslider, SLOT(addStep()));

These are the error messages from the console for my code below in main.cpp: "QObject::connect: No such slot QSlider::SingleStep()in ..\ProgrammingQt\main.cpp:31 QObject::connect: No such signal QSlider::triggerAction(SliderSingleStepAdd) in ..\ProgrammingQt\main.cpp:32"

Here is my code without the ui. - main.cpp

#include <iostream>

#include <qapplication.h>
#include <qwidget.h>
#include <qslider.h>
#include <qlcdnumber.h>
#include <qpushbutton.h>
#include <qstring.h>

using namespace std;

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);

    QWidget *widget = new QWidget();
    widget->setGeometry(400, 300, 170, 150);

    QSlider *slider = new QSlider(Qt::Horizontal, widget);
    slider->setGeometry(10, 10, 150,30);

    QLCDNumber *lcd = new QLCDNumber(2, widget);
    lcd->setGeometry(60, 50, 50, 50);
    lcd->display(1);

    QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));

    QPushButton *addBtn = new QPushButton("ADD ONE", widget);
    addBtn->setGeometry(10, 110, 50, 30);
    //QObject::connect(addBtn, SIGNAL(clicked(bool)), slider, SLOT(SliderSingleStepAdd()));
    //QObject::connect(addBtn, SIGNAL(clicked(bool)), slider, SLOT(SingleStep()));
    //QObject::connect(slider, SIGNAL(triggerAction(SliderSingleStepAdd)), lcd, SLOT(display(int)));

    QPushButton *minusBtn = new QPushButton("MINUS ONE", widget);
    minusBtn->setGeometry(100, 110, 60, 30);
   //  QObject::connect(minusBtn, SIGNAL(clicked(bool)), slider, SLOT    (SliderSingleStepSub()));

    QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));

    widget->setWindowTitle("LCD Number");
    widget->show();
    return app.exec();
}

Here is the code using the Qt Designer: mainwindow.cpp

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

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

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

void MainWindow::on_slider_valueChanged(int value)
{
    ui->lcd->display(value);
}

void MainWindow::on_addBtn_clicked()
{
    int incVal = ui->slider->value();
    incVal++;
    ui->slider->setValue(incVal);
    ui->lcd->display(incVal);
}

void MainWindow::on_minusBtn_clicked()
{
    int decVal = ui->slider->value();
    decVal--;
    ui->slider->setValue(decVal);
    ui->lcd->display(decVal);
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSlider>
#include <QLCDNumber>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

   private slots:

   void on_slider_valueChanged(int value);

   void on_addBtn_clicked();
   void on_minusBtn_clicked();

 private:
     Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

Upvotes: 1

Views: 647

Answers (1)

Tarod
Tarod

Reputation: 7170

The slots SliderSingleStepAdd, SingleStep or SliderSingleStepSub are not found because there are not defined in the object slider.

According to the documentation,

All classes that inherit from QObject or one of its subclasses (e.g., QWidget) can contain signals and slots.

So you need a class where you must implement your required signals and slots.

For example, your main should be something like this:

#include <iostream>

#include <qapplication.h>
#include <qwidget.h>
#include <qslider.h>
#include <qlcdnumber.h>
#include <qpushbutton.h>
#include <qstring.h>
#include <myclass.h>

using namespace std;

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);

    MyClass myClass;

    QWidget *widget = new QWidget();
    widget->setGeometry(400, 300, 170, 150);

    QSlider *slider = new QSlider(Qt::Horizontal, widget);
    slider->setGeometry(10, 10, 150,30);

    QLCDNumber *lcd = new QLCDNumber(2, widget);
    lcd->setGeometry(60, 50, 50, 50);
    lcd->display(1);

    QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));

    QPushButton *addBtn = new QPushButton("ADD ONE", widget);
    addBtn->setGeometry(10, 110, 50, 30);
    QObject::connect(addBtn, SIGNAL(clicked(bool)), &myClass, SLOT(SliderSingleStepAdd()));
    QObject::connect(addBtn, SIGNAL(clicked(bool)), &myClass, SLOT(SingleStep()));
    // QObject::connect(slider, SIGNAL(triggerAction(SliderSingleStepAdd)), lcd, SLOT(display(int)));

    QPushButton *minusBtn = new QPushButton("MINUS ONE", widget);
    minusBtn->setGeometry(100, 110, 60, 30);
    QObject::connect(minusBtn, SIGNAL(clicked(bool)), &myClass, SLOT(SliderSingleStepSub()));

    QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));

    widget->setWindowTitle("LCD Number");
    widget->show();
    return app.exec();
}

And you should have a class like the following one:

#ifndef MYCLASS_H
#define MYCLASS_H

#include <iostream>
#include <QObject>

class MyClass : public QObject
{
   Q_OBJECT

public:
    MyClass(): QObject() {}
    virtual ~MyClass() {}

   public slots:
    void SliderSingleStepAdd ()
    {
        std::cout << "SliderSingleStepAdd" << std::endl;
    }

    void SingleStep ()
    {
        std::cout << "SingleStep" << std::endl;
    }

    void SliderSingleStepSub ()
    {
        std::cout << "SliderSingleStepSub" << std::endl;
    }

};

#endif // MYCLASS_H

In my opinion, all your objects (slider, lcd and buttons) should be in a class that inherits from QWidget so you can connect those objects. This should be also necessary in case of the following connect:

QObject::connect(slider, SIGNAL(triggerAction(SliderSingleStepAdd)), lcd, SLOT(display(int)));

Upvotes: 0

Related Questions