Reputation: 109
I'm working on a computer vision project, an interactable surface that must handle user interactions through the video feed recognising the user's hands. The system recognizes the user's finger and map it on a GUI. I've developed the solution in Visual Studio 2017 using OpenCV for the video processing stuff, QT 5 to build the GUI and arduino to check the click on the surface. At the moment I've to controll a QTPushButton using the arduino serial output, that controll a boolean (isChecked) in the main class of the C++ program, I've read a lot about SIGNAL and SLOT in QT but when I trigger a SIGNAL using arduino serial connection and I handle the signal with connect() method in the MainWindow interface the system responds with the error : QObject::connect: No such signal QPushButton::valueChangedButton1(unsigned int).
The program failed to connect(button1, SIGNAL(valueChangedButton1(unsigned int)), this, SLOT(button1clicked()));, in the MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) instance.
SerialPort.h is an utility class to handle serial output from arduino. I've tried to put the connect() method in the while cycle of openCV but doesn't work.
MainWindow.h
#define NSAMPLES 7
#define ORIGCOL2COL COLOR_BGR2HLS
#define COL2ORIGCOL COLOR_HLS2BGR
#define PI 3.14159
#include <QtWidgets/QMainWindow>
#include <QtCore/qcoreapplication.h>
#include <QtGui/qtguiglobal.h>
#include <iostream>
#include "ui_MainWindow.h"
#include "opencv2/opencv.hpp"
#include "SerialPort.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = Q_NULLPTR);
private:
void initializationClicked();
void stopCapture();
void button1clicked();
void button2clicked();
signals:
void valueChangedButton1(unsigned int value);
private:
QPushButton *startCapture;
QPushButton *releaseCapture;
QPushButton *button1;
QPushButton *button2;
QLabel *interactionLabel;
QLabel *interactionType;
QFont f, i;
char *PORT;
bool b1Over, b2Over, isChecked;
// opencv stuff
cv::VideoCapture cap;
cv::Mat src;
// arduino stuff
char output[MAX_DATA_LENGTH];
char incomingData[MAX_DATA_LENGTH];
int intFromArduino;
char *port;
int fromArduino;
}
MainWindow.cpp
#include "MainWindow.h"
using namespace cv;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
f = QFont("Arial", 12, QFont::Bold);
i = QFont("Arial", 10, QFont::Black);
PORT = "\\\\.\\COM5";
width = 600;
height = 380;
setMinimumSize(width, height);
startCapture = new QPushButton("INIT SYSTEM", this);
startCapture->setGeometry(QRect(QPoint(10, height - 120), QSize(100, 50)));
connect(startCapture, SIGNAL(clicked()), this, SLOT(initializationClicked()));
releaseCapture = new QPushButton("KILL SYSTEM", this);
releaseCapture->setGeometry(QRect(QPoint(10, height - 60), QSize(100, 50)));
connect(releaseCapture, SIGNAL(clicked()), this, SLOT(stopCapture()));
button1 = new QPushButton("BUTTON 1", this);
button1->setGeometry(QRect(QPoint(width / 2 - 100, height - 120), QSize(150, 100)));
b1 = Point(width / 2 - 100, height - 120);
// receive the signal
connect(button1, SIGNAL(valueChangedButton1(unsigned int)), this, SLOT(button1clicked()));
button2 = new QPushButton("BUTTON 2", this);
button2->setGeometry(QRect(QPoint(width / 2 + 100, height - 120), QSize(150, 100)));
b2 = Point(width / 2 + 100, height - 120);
interactionLabel = new QLabel(this);
interactionLabel->setText("log: ");
interactionLabel->setGeometry(QRect(QPoint(10, 15), QSize(200, 20)));
interactionLabel->setFont(f);
interactionType = new QLabel(this);
interactionType->setText("kind of interaction");
interactionType->setGeometry(QRect(QPoint(110,15), QSize(250, 20)));
interactionType->setFont(i);
}
void MainWindow::initializationClicked()
{
controllMainVideoFlow();
}
void MainWindow::controllMainVideoFlow()
{
SerialPort arduino(PORT);
cap = VideoCapture(0);
if(!cap.isOpen())
{
cout << "no video feed" << endl;
}else
{
if(arduino.isConnected())
{
while(cap.isOpen())
{
cap >> src;
arduino.readSerialPort(output, MAX_DATA_LENGTH);
fromArduino = strlen(output);
if(fromArduino == 0)
{
isChecked = false;
}
else if(fromArduino != 0)
{
isChecked = true;
// emit the signal
emitSignalB1();
}
imshow("SOURCE", src);
qApp->processEvents();
if (cv::waitKey(30) == 'q') break;
}
cap.release();
src.release();
}
}
}
void MainWindow::emitSignalB1()
{
// emit the signal
emit valueChangedButton1(fromArduino);
}
void MainWindow::stopCapture()
{
interactionType->setText("system killed");
cap.release();
src.release();
destroyAllWindows();
}
void MainWindow::button1clicked()
{
interactionType->setText("button 1 clicked");
}
void MainWindow::button2clicked()
{
interactionType->setText("button 2 clicked");
}
Upvotes: 1
Views: 2707
Reputation: 6805
The error is here:
connect(button1, SIGNAL(valueChangedButton1(unsigned int)), this, SLOT(button1clicked()));
Actually, there is no such signal called valueChangedButton1()
in QPushButton
. You get this error because button1
is a QPushButton
.
You defined this signal in the MainWindow
class, so you have to connect the signal from a MainWindow
instance, not from a QPushButton
instance.
You could write instead:
connect(this, SIGNAL(valueChangedButton1(unsigned int)), this, SLOT(button1clicked()));
// ^
// Not button1
This will fix your error.
But as it's not clear for me what you really want to do, I'm not sure if it is what you really want.
By the way, I think this is a typo but, in your header, you declared your signal as signal:
instead of signals:
(a 's' is missing).
EDIT: I would advise you to not use the old macros SIGNAL()
and SLOT()
anymore. You should use the new syntax instead.
Moreover, as the new syntax makes explicit from where the signals and slots are called, the origin of this error would have been obvious.
Upvotes: 3