Reputation: 11
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
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