Using Signals and Slots
-
I have created my own Slider class using QSlider widget.
I want the QLCDNumber Widget to be implemented inside main.cpp.
I have not created the connection between the two widgets yet.
Do I have to write the definition of valueChanged() as a signal?I am getting the following errors:
-
symbol(s) not found for architecture x86_64
-
linker command failed with exit code 1 (use -v to see invocation)
Please take a look at my code:
main.cpp:
#include <QSlider> #include <QLCDNumber> #include <QApplication> #include <QVBoxLayout> #include "slider.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); Slider *slider = new Slider(Qt::Horizontal); slider->setRange(-100, 100); slider->setValue(20); QLCDNumber *lcd = new QLCDNumber; lcd->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); QWidget *top = new QWidget; QVBoxLayout *layout = new QVBoxLayout(top); layout->addWidget(slider); layout->addWidget(lcd); top->show(); return app.exec(); }
slider.cpp:
#include "slider.h" Slider::Slider(Qt::Orientation orient, QWidget *parent) : QWidget(parent) { m_slider = new QSlider(orient); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(m_slider); setLayout(layout); } void Slider::setRange(int min, int max) { m_slider->setRange(min, max); } void Slider::setValue(int newValue) { if (newValue != m_value) { m_slider->setValue(newValue); m_value = newValue; emit m_slider->valueChanged(newValue); } } void Slider::valueChanged(int newValue){ m_slider->valueChanged(newValue); }
slider.h:
#ifndef SLIDER_H #define SLIDER_H #include <QSlider> #include <QVBoxLayout> class QSlider; class Slider : public QWidget { Q_OBJECT public: Slider(Qt::Orientation orient = Qt::Horizontal, QWidget *parent = 0); void setRange(int min, int max); public slots: void setValue(int val); signals: void valueChanged(int newValue); private: QSlider *m_slider; int m_value; }; #endif // SLIDER_H
-
-
I have created my own Slider class using QSlider widget.
I want the QLCDNumber Widget to be implemented inside main.cpp.
I have not created the connection between the two widgets yet.
Do I have to write the definition of valueChanged() as a signal?I am getting the following errors:
-
symbol(s) not found for architecture x86_64
-
linker command failed with exit code 1 (use -v to see invocation)
Please take a look at my code:
main.cpp:
#include <QSlider> #include <QLCDNumber> #include <QApplication> #include <QVBoxLayout> #include "slider.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); Slider *slider = new Slider(Qt::Horizontal); slider->setRange(-100, 100); slider->setValue(20); QLCDNumber *lcd = new QLCDNumber; lcd->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); QWidget *top = new QWidget; QVBoxLayout *layout = new QVBoxLayout(top); layout->addWidget(slider); layout->addWidget(lcd); top->show(); return app.exec(); }
slider.cpp:
#include "slider.h" Slider::Slider(Qt::Orientation orient, QWidget *parent) : QWidget(parent) { m_slider = new QSlider(orient); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(m_slider); setLayout(layout); } void Slider::setRange(int min, int max) { m_slider->setRange(min, max); } void Slider::setValue(int newValue) { if (newValue != m_value) { m_slider->setValue(newValue); m_value = newValue; emit m_slider->valueChanged(newValue); } } void Slider::valueChanged(int newValue){ m_slider->valueChanged(newValue); }
slider.h:
#ifndef SLIDER_H #define SLIDER_H #include <QSlider> #include <QVBoxLayout> class QSlider; class Slider : public QWidget { Q_OBJECT public: Slider(Qt::Orientation orient = Qt::Horizontal, QWidget *parent = 0); void setRange(int min, int max); public slots: void setValue(int val); signals: void valueChanged(int newValue); private: QSlider *m_slider; int m_value; }; #endif // SLIDER_H
@JimmyMars said in Using Signals and Slots:
Do I have to write the definition of valueChanged() as a signal?
No, you only declare it in your class as signal, definition is done by moc compiler.
Remove this:void Slider::valueChanged(int newValue){ m_slider->valueChanged(newValue); }
Regarding your errors: what Qt version? Operating system? Do you use QtCreator? Please post the whole error messages.
-
-
@JimmyMars said in Using Signals and Slots:
Do I have to write the definition of valueChanged() as a signal?
No, you only declare it in your class as signal, definition is done by moc compiler.
Remove this:void Slider::valueChanged(int newValue){ m_slider->valueChanged(newValue); }
Regarding your errors: what Qt version? Operating system? Do you use QtCreator? Please post the whole error messages.
-
@jsulm
Qt 5.8.0 (Clang 7.0 (Apple))
macOS Sierra
QtCrreator 4.3.0That was the whole error message:
@JimmyMars Please go to "Compile Output" to get whole error messages.
But first change the code as I said. -
@JimmyMars Please go to "Compile Output" to get whole error messages.
But first change the code as I said.@jsulm
I have removed the definition of valueChanged now.Still getting this error:
0:50:34: Running steps for project lab-slider... 10:50:34: Configuration unchanged, skipping qmake step. 10:50:34: Starting: "/usr/bin/make" /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -stdlib=libc++ -headerpad_max_install_names -arch x86_64 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -mmacosx-version-min=10.10 -Wl,-rpath,@executable_path/Frameworks -Wl,-rpath,/Users/gautam/Qt/5.9/clang_64/lib -o lab-slider.app/Contents/MacOS/lab-slider main.o slider.o -F/Users/gautam/Qt/5.9/clang_64/lib -framework QtWidgets -framework QtGui -framework QtCore -framework DiskArbitration -framework IOKit -framework OpenGL -framework AGL Undefined symbols for architecture x86_64: "vtable for Slider", referenced from: Slider::Slider(Qt::Orientation, QWidget*) in slider.o NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [lab-slider.app/Contents/MacOS/lab-slider] Error 1 10:50:34: The process "/usr/bin/make" exited with code 2. Error while building/deploying project lab-slider (kit: Desktop Qt 5.9.0 clang 64bit) When executing step "Make" 10:50:34: Elapsed time: 00:00.
-
To add to jsulm
you need code to emit the signal or you can connect it to another signal (e.g. of QSlider).
@koahnig said in Using Signals and Slots:
To add to jsulm
you need code to emit the signal or you can connect it to another signal (e.g. of QSlider).
isn't
emit
a placeholder? Andemit mySignal();
acts the same asmySignal();
But it gets quickly confusing if you omit the
emit
! -
@koahnig said in Using Signals and Slots:
To add to jsulm
you need code to emit the signal or you can connect it to another signal (e.g. of QSlider).
isn't
emit
a placeholder? Andemit mySignal();
acts the same asmySignal();
But it gets quickly confusing if you omit the
emit
! -
@jsulm
I have removed the definition of valueChanged now.Still getting this error:
0:50:34: Running steps for project lab-slider... 10:50:34: Configuration unchanged, skipping qmake step. 10:50:34: Starting: "/usr/bin/make" /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -stdlib=libc++ -headerpad_max_install_names -arch x86_64 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -mmacosx-version-min=10.10 -Wl,-rpath,@executable_path/Frameworks -Wl,-rpath,/Users/gautam/Qt/5.9/clang_64/lib -o lab-slider.app/Contents/MacOS/lab-slider main.o slider.o -F/Users/gautam/Qt/5.9/clang_64/lib -framework QtWidgets -framework QtGui -framework QtCore -framework DiskArbitration -framework IOKit -framework OpenGL -framework AGL Undefined symbols for architecture x86_64: "vtable for Slider", referenced from: Slider::Slider(Qt::Orientation, QWidget*) in slider.o NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [lab-slider.app/Contents/MacOS/lab-slider] Error 1 10:50:34: The process "/usr/bin/make" exited with code 2. Error while building/deploying project lab-slider (kit: Desktop Qt 5.9.0 clang 64bit) When executing step "Make" 10:50:34: Elapsed time: 00:00.
@JimmyMars How did you add Slider class? Manually or using QtCreator wizard?
-
@JimmyMars How did you add Slider class? Manually or using QtCreator wizard?
-
@JimmyMars Then either read and follow http://doc.qt.io/qt-5.9/moc.html or do it using QtCreator wizard.
QObject derived classes need special handling using moc meta compiler from Qt. This isusually done for you, but not if you add a class manually. -
@JimmyMars Actually it should work without any manual work if you use qmake.
Can you show your pro file? -
@JimmyMars Actually it should work without any manual work if you use qmake.
Can you show your pro file? -
I think there needs to be:
QT += core gui widgetsI have it currently like this.
HEADERS= slider.h SOURCES= main.cpp slider.cpp OTHER_FILES += \ readme.txt QT += widgets
TEMPLATE = app QT += core gui widgets
-
TEMPLATE = app QT += core gui widgets
-
To solve this problem, you need to follow the steps below.
-
In slider.cpp, change this expression emit m_slider->valueChanged(newValue) to emit valueChanged(newValue).
-
In slider.cpp, remove the implementation of valueChanged method. This means you need to remove the following part.
void Slider::valueChanged(int newValue){
m_slider->valueChanged(newValue);
}Build it and you will find everything goes well.
Why?
When you declare valueChanged in slider.h with signals Macro as well as QObject Macro. It means Qt's moc compiler will help you deal with the implementation of valueChanged. So you shouldn't implement it. Unlike other C++ code, when you declare some method in .h file, you need to implement it in .cpp file. Actually, Qt follows this, but it has already made it done.
-