Unsolved Elemental signal and slot example
-
Hi there. I'm trying to understand the signal and slot mechanism; but I'm afraid that I have no idea of what I'm doing.
I have set up a simple example, that doesn't work, and ends in a "the slot requires more arguments than the signal provide" error. The theoretical behavior is really simple, there is a login screen with a user and password text, and when you click the button, the widget signal those two strings to a controller, and the controller do something with it. In this case, it just show them in the stdout.
Here is all the code I have so far:
controller.h
#ifndef CONTROLLER_H #define CONTROLLER_H #include <QObject> #include <QString> class Controller : public QObject { Q_OBJECT public: explicit Controller(QObject *parent = 0); signals: public slots: void doSomething(QString user, QString pass); }; #endif // CONTROLLER_H
loginScreen.h
#ifndef LOGINSCREEN_H #define LOGINSCREEN_H #include <QDialog> #include "controller.h" namespace Ui { class LoginScreen; } class LoginScreen : public QDialog { Q_OBJECT public: explicit LoginScreen(QWidget *parent = 0); ~LoginScreen(); signals: void on_pushButton_clicked(); private: Ui::LoginScreen *ui; }; #endif // LOGINSCREEN_H
controller.cpp
#include "controller.h" #include <iostream> #include <QTextStream> Controller::Controller(QObject *parent) : QObject(parent) { } void Controller::doSomething(QString user, QString pass){ QTextStream(stdout) << "Doing something..."<<user<<" "<<pass<< endl; }
loginscreen.cpp
#include "loginscreen.h" #include "ui_loginscreen.h" LoginScreen::LoginScreen(QWidget *parent) : QDialog(parent), ui(new Ui::LoginScreen) { ui->setupUi(this); } LoginScreen::~LoginScreen() { delete ui; } void LoginScreen::on_pushButton_clicked() { emit (this->ui->userLine->text(),this->ui->passwordLine->text()); }
main.cpp
#include "loginscreen.h" #include "controller.h" #include <QApplication> #include <QObject> int main(int argc, char *argv[]) { QApplication a(argc, argv); Controller mainControl; LoginScreen w; QObject::connect(&w, &LoginScreen::on_pushButton_clicked, &mainControl, &Controller::doSomething); w.show(); return a.exec(); }
And finally, the loginscreen.ui
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>LoginScreen</class> <widget class="QDialog" name="LoginScreen"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>214</width> <height>146</height> </rect> </property> <property name="windowTitle"> <string>Dialog</string> </property> <widget class="QLabel" name="statusLabel"> <property name="geometry"> <rect> <x>10</x> <y>10</y> <width>47</width> <height>13</height> </rect> </property> <property name="text"> <string>Ready...</string> </property> </widget> <widget class="QLabel" name="userLabel"> <property name="geometry"> <rect> <x>10</x> <y>40</y> <width>47</width> <height>13</height> </rect> </property> <property name="text"> <string>User</string> </property> </widget> <widget class="QLabel" name="passwordLabel"> <property name="geometry"> <rect> <x>10</x> <y>70</y> <width>47</width> <height>13</height> </rect> </property> <property name="text"> <string>Password</string> </property> </widget> <widget class="QLineEdit" name="userLine"> <property name="geometry"> <rect> <x>70</x> <y>40</y> <width>113</width> <height>20</height> </rect> </property> </widget> <widget class="QLineEdit" name="passwordLine"> <property name="geometry"> <rect> <x>70</x> <y>70</y> <width>113</width> <height>20</height> </rect> </property> </widget> <widget class="QPushButton" name="pushButton"> <property name="geometry"> <rect> <x>70</x> <y>110</y> <width>75</width> <height>23</height> </rect> </property> <property name="text"> <string>Login</string> </property> </widget> </widget> <resources/> <connections/> </ui>
So the question would be, what would be the correct "connect" function? I have read, watch and follow different tutorials and documentations and I'm still really confuse on how are those two arguments suppose to pass from one place to the other.
-
hi and welcome
The reason the connect dont like you is because
doSomething has parameters and
on_pushButton_clicked dont.You just just need to define a new signal in LoginScreen ( like the slot)
public signals:
void doSomething(QString user, QString pass);then in on_pushButton_clicked(); ( which is called when u click button)
u emit this signal
emit doSomething (this->ui->userLine->text(),this->ui->passwordLine->text());and from outside u have connect the 2 "doSomething "
so in short, the button clicked is hooked to local slot.
The local slot will then emit your signal with parameters.
From outside, this signal is connected to a slot with same signature. ( same params)Hope I explained it good enough.
-
TEMP_EDIT: How do I mark the post as solved??
Thank you! ; it took me a little bit but I got it. I'm leaving here the final code in case someone need it:
controller.h stays the same.
controller.cpp stays the same.#ifndef LOGINSCREEN_H #define LOGINSCREEN_H #include <QDialog> #include "controller.h" namespace Ui { class LoginScreen; } class LoginScreen : public QDialog { Q_OBJECT public: explicit LoginScreen(QWidget *parent = 0); ~LoginScreen(); signals: void doSomething(QString user, QString pass); public slots: void on_pushButton_clicked(); private: Ui::LoginScreen *ui; }; #endif // LOGINSCREEN_H
loginScreen.cpp
#include "loginscreen.h" #include "ui_loginscreen.h" LoginScreen::LoginScreen(QWidget *parent) : QDialog(parent), ui(new Ui::LoginScreen) { ui->setupUi(this); } LoginScreen::~LoginScreen() { delete ui; } void LoginScreen::on_pushButton_clicked() { emit doSomething(this->ui->userLine->text(),this->ui->passwordLine->text()); }
main.cpp
#include "loginscreen.h" #include "controller.h" #include <QApplication> #include <QObject> int main(int argc, char *argv[]) { QApplication a(argc, argv); Controller mainControl; LoginScreen w; QObject::connect(&w, &LoginScreen::doSomething, &mainControl, &Controller::doSomething); w.show(); return a.exec(); }