Not able to connect to the slot in qt - c++

Here i am adding part of my code, i have my main function and MainWindow class
Basically my init() function should be triggered in order to fill my display_images queue in timercalldisplay() function so i am calling it from my main
But i am not able to get in to timercalldisplay() calling it through SLOT and init() is getting executed
Can anybody say what mistake i was doing
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void init();
QTimer *timer;
public slots:
void timercalldisplay();
private:
Ui::MainWindow *ui;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
w.init();
return a.exec();
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(timercalldisplay()));
timer->start(500);
}
void MainWindow::timercalldisplay()
{
qDebug() << display_images.size(); //not reaching here
while(display_images.size())
{
Mat img = display_images.front();
QPixmap pixmap;
QImage qimg(img.data, img.cols, img.rows, img.step, QImage::Format_RGB888);
pixmap = QPixmap::fromImage(qimg.rgbSwapped());
ui->label->setPixmap(pixmap);
ui->label->setScaledContents(true);
ui->label->show();
QThread::currentThread()->msleep(1000);
qApp->processEvents();
display_images.pop();
}
}

connect(timer, SIGNAL(timeout()), this, SLOT(timercalldisplay()));
take the () out of the connect like
fixed
connect(timer, &QTimer::timeout, this, &MainWindow::timercalldisplay);
Also in you constructor change
QTimer *timer = new QTimer(this);
to
timer = new QTimer(this);
Update based on new issue

Related

display 2 QML files on a single QQuickwidget alternately when required without overlap

I have a QQuickwidget in a Qt C++ application where i have loaded a QML file (main.qml) and using QAction(actionstart) and C++ functions i have to load another QML file(main1.qml) slightly different to previous one on the same QQuickWidget object.
I am able to do this , but my 2nd QML file is overlapped from the middle section of QQuickwidget and further.
I have did this to stop overlapping of 2 QML files but not successful completely. count3 = 1 is defined in public section of Guiapplication.h file.
void GuiApplication::on_actionstart_triggered()
{
if (count3 == 1)
{
set_animation();
count3 = 2;
}
}
C++ Function for loading 1st QML file(main.qml)
void GuiApplication::rolling_animation()
{
QQuickView *quickWidget=new QQuickView();
QWidget *contain = QWidget::createWindowContainer(quickWidget,this);
contain->setMinimumSize(1008,349);
contain->setMaximumSize(1008,349);
contain->setFocusPolicy(Qt::TabFocus);
quickWidget->setSource(QUrl("qrc:/Resources/main.qml"));
ui->horizontalLayout_6->addWidget(contain);
}
C++ Function for loading 2nd QML file(main1.qml)
void GuiApplication::set_animation()
{
QQuickView *quickWidget=new QQuickView();
QWidget *Contain = QWidget::createWindowContainer(quickWidget,this);
Contain->setMinimumSize(1008,349);
Contain->setMaximumSize(1008,349);
Contain->setFocusPolicy(Qt::TabFocus);
quickWidget->setSource(QUrl("qrc:/Resources/main1.qml"));
ui->horizontalLayout_6->addWidget(Contain);
//ui->horizontalLayout_9->invalidate();
//ui->horizontalLayout_9->removeWidget(quickWidget_4);
}
output window image
Depending on whether you want to save or not the state of the QML that you want to hide there are the following alternatives:
Reject the same QQuickWidget (I recommend changing QQuickView to QQuickWidget) and just change the source.
#include <QtQuickWidgets>
class Widget: public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent=nullptr):
QWidget(parent),
m_widget(new QQuickWidget)
{
m_widget->setResizeMode(QQuickWidget::SizeRootObjectToView);
QPushButton *button1 = new QPushButton("show 1");
QPushButton *button2 = new QPushButton("show 2");
QHBoxLayout *lay = new QHBoxLayout(this);
QVBoxLayout *vlay = new QVBoxLayout;
vlay->addWidget(button1);
vlay->addWidget(button2);
lay->addLayout(vlay);
lay->addWidget(m_widget);
connect(button1, &QPushButton::clicked, this, &Widget::show1);
connect(button2, &QPushButton::clicked, this, &Widget::show2);
show1();
}
private slots:
void show1(){
m_widget->setSource(QUrl("qrc:/main1.qml"));
}
void show2(){
m_widget->setSource(QUrl("qrc:/main2.qml"));
}
private:
QQuickWidget *m_widget;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "main.moc"
Use 2 QuickWidgets and use a QStackedWidget to toggle the widgets, with this method only hidden so the state of the QML will persist, in the previous case when changing the source is lost.
#include <QtQuickWidgets>
class Widget: public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent=nullptr):
QWidget(parent),
m_stacked_widget(new QStackedWidget)
{
for(const QString & url: {"qrc:/main1.qml", "qrc:/main2.qml"}){
QQuickWidget *widget = new QQuickWidget;
widget->setResizeMode(QQuickWidget::SizeRootObjectToView);
widget->setSource(QUrl(url));
m_stacked_widget->addWidget(widget);
}
QPushButton *button1 = new QPushButton("show 1");
QPushButton *button2 = new QPushButton("show 2");
QHBoxLayout *lay = new QHBoxLayout(this);
QVBoxLayout *vlay = new QVBoxLayout;
vlay->addWidget(button1);
vlay->addWidget(button2);
lay->addLayout(vlay);
lay->addWidget(m_stacked_widget);
connect(button1, &QPushButton::clicked, this, &Widget::show1);
connect(button2, &QPushButton::clicked, this, &Widget::show2);
show1();
}
private slots:
void show1(){
m_stacked_widget->setCurrentIndex(0);
}
void show2(){
m_stacked_widget->setCurrentIndex(1);
}
private:
QStackedWidget *m_stacked_widget;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "main.moc"
The examples can be found here

How to start and stop usb camera streaming using openCV by clicking a button and paint it into a custom widget on Qt?

I'm quite new on qt. I'm trying to create a tab on my ui that can give the option to count how many usb cameras are connected to computer and list then using OPENCV. After that, I want to select one of then and start streaming a video into a custom widget, using paintEvent. My main difficulties are: how to start and stop a streaming when a button is pressed. Below i'm posting my code.
mainwindow.h
//includes...
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void on_CheckCamerasButton_clicked();
void on_StartStreamingButton_clicked();
private:
Ui::MainWindow *ui;
cameraimage camera;
};
#endif // MAINWINDOW_H
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_StartStreamingButton_clicked(){
camera.startStreaming();
}
void MainWindow::on_CheckCamerasButton_clicked(){
camera.stopStreaming();
}
cameraimage.h
//includes...
class cameraimage : public QWidget
{
Q_OBJECT
public:
explicit cameraimage(QWidget *parent = nullptr);
private:
QPoint mPoint;
QTimer *timer;
cv::VideoCapture captureVideo;
public slots:
void paintEvent(QPaintEvent * event);
void startStreaming();
void stopStreaming();
};
#endif // CAMERAIMAGE_H
cameraimage.cpp
#include "cameraimage.h"
cameraimage::cameraimage(QWidget *parent) : QWidget(parent)
{
setMouseTracking(true);
}
void cameraimage::startStreaming(){
qDebug() << "Starting Streaming";
captureVideo.open(-1);
if (captureVideo.isOpened() == false){
qDebug() << "Camera can't open";
return;
}
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1);
}
void cameraimage::stopStreaming(){
captureVideo.release();
timer->stop();
}
void cameraimage::paintEvent(QPaintEvent *){
cv::Mat tmpImage;
cv::Mat image;
captureVideo.read(tmpImage);
if (tmpImage.empty() == true){
qDebug() << "EMPTY!";
return;
}
cv::cvtColor(tmpImage, image, CV_BGR2RGB);
QImage img((const unsigned char*)(image.data), image.cols, image.rows, QImage::Format_RGB888);
QPixmap pixmap = QPixmap::fromImage(img);
QPainter painter(this);
float comprimento = 1.0*width()/pixmap.width();
float altura = 1.0*height()/pixmap.height();
float ratio = 0.;
if (comprimento<=altura)
ratio = comprimento;
else
ratio = altura;
QSize size = ratio*pixmap.size();
size.setHeight(size.height()-10);
QPoint p;
p.setX(0 + (width()-size.width())/2);
p.setY(5);
painter.drawPixmap(QRect(p, size), pixmap.scaled(size, Qt::KeepAspectRatio));
}
I've got the following output after clicked on StartStreamingButton on MainWindow:
Starting Streaming...
EMPTY!
EMPTY!
EMPTY!
...
Can someone help me please?
Best regards :D

Want to add pushbutton to setTimer and setText

I am newbie in GUI design. Here, in sending and receiving messages (float, integer values) using DDS (OpenSplice) I am trying to add a pushButton to my already existing labels(displaying some float values as shown below), so that after a clicking on the pushButton, I should be able to see data in my label.
I tried adding a push button with the help of Qt Network sender Example. Now I get the error undefined reference to 'MainWindow::on_pushButton_clicked() in the file moc_mainwindow.cpp while building the project.
fastsender.cpp
FastSender::FastSender(QLabel *x, QObject *parent) : QObject(parent)
{
wSend = x;
dataTimer = new QTimer(this);
emergency = new QPushButton(tr("Emergency"));
buttonBox = new QDialogButtonBox;
buttonBox->addButton(emergency,QDialogButtonBox::ActionRole);
connect(emergency, SIGNAL(clicked()), this, SLOT(startsending()));
connect(dataTimer, SIGNAL(timeout()), this, SLOT(walk()));
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(buttonBox);
}
void FastSender::startsending()
{
emergency->setEnabled(false);
dataTimer->start(100); // Interval 0 means to refresh as fast as possible
}
int FastSender::walk()
{
msg->value= i+0.1;
snprintf (buf, MAX_MSG_LEN, "Message no. %d", i);
cout << "Writing message: \"" << msg->value << "\"" << endl;
status = talker->write(*msg, userHandle);
QString s= QString::number(msg->value, 'f',8);
wSend->setText(s);
}
fastsender.h
class FastSender : public QObject
{
Q_OBJECT
public:
explicit FastSender(QObject *parent = 0);
FastSender(QLabel *x, QObject *parent = 0);
~FastSender();
signals:
private:
QTimer* dataTimer;
QLabel *wSend;
DDS::DomainParticipantFactory_var dpf;
DDS::DomainParticipant_var parentDP;
DDS::Topic_var signalTopic;
DDS::DataReader_var parentReader;
DDS::DataWriter_var parentWriter;
fw::signalSeq_var msgSeq;
char * signalTypeName;
fw::signalDataWriter_var talker;
fw::signal *msg;
DDS::InstanceHandle_t userHandle;
DDS::Publisher_var fwPublisher;
int alpa;
QPushButton *emergency;
QDialogButtonBox *buttonBox;
public slots:
int walk();
int hello();
void startsending();
};
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
fwdds = new FastWanDDS(ui->label);//receiving values are displayed in label
fwdds1 = new FastSender(ui->label_2);//Sending values are displayed in label_2
}
mainwindow.h
Ui::MainWindow *ui;
QTimer* timer;
int counter;
FastWanDDS *fwdds;
FastSender *fwdds1;
Any Help Appreciated.
Note: Only snippets of the code presented
I got it to work this way. Does this work for you?
mainwindow.cpp
#include "mainwindow.h"
#include "fastsender.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QLabel* label = new QLabel("unchanged");
FastSender* fs = new FastSender(label);
setCentralWidget(fs);
}
MainWindow::~MainWindow()
{
}
fastsender.h
#ifndef FASTSENDER_H
#define FASTSENDER_H
#include <QLabel>
#include <QTimer>
#include <QPushButton>
#include <QDialogButtonBox>
#include <QHBoxLayout>
class FastSender : public QWidget
{
Q_OBJECT
public:
FastSender(QLabel* label, QWidget* parent = 0)
: QWidget(parent)
, _label(label)
, _timer(new QTimer)
, _emergency(new QPushButton(tr("Emergency")))
, _bbox(new QDialogButtonBox)
{
_bbox->addButton(_emergency, QDialogButtonBox::ActionRole);
QHBoxLayout* layout = new QHBoxLayout;
layout->addWidget(_label);
layout->addWidget(_bbox);
setLayout(layout);
connect(_emergency, SIGNAL(clicked(bool)), this, SLOT(startsending()));
connect(_timer, SIGNAL(timeout()), this, SLOT(walk()));
}
public slots:
void startsending()
{
_emergency->setEnabled(false);
_timer->start(100);
}
int walk()
{
_label->setText("changed");
_emergency->setEnabled(true);
}
private:
QLabel* _label;
QTimer* _timer;
QPushButton* _emergency;
QDialogButtonBox* _bbox;
};
#endif // FASTSENDER_H

Program runs but nothing displays Qt c++

Hi my program runs with no errors but nothing is displayed on screen, a window is meant to pop up which runs another program with a QProcess, this program runs fine. code follows:
header file:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtGui>
#include <QTimer>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void setTimer();
void displayAdvice();
void cancelTimer();
void addAdvice();
void processDone(int);
private:
QLabel* timerLbl;
QLineEdit* timerEdt;
QTextEdit* adviceEdt;
QPushButton* okBtn;
QPushButton* cancelBtn;
QTimer* timer;
QProcess *process;
void setupGui();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setupGui();
}
Widget::~Widget()
{
delete ui;
}
void Widget::setupGui()
{
timerLbl = new QLabel("Timer set interval in seconds");
timerEdt = new QLineEdit();
adviceEdt = new QTextEdit();
this->adviceEdt->setReadOnly(true);
okBtn = new QPushButton("OK");
cancelBtn = new QPushButton("Cancel");
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(timerLbl);
layout->addWidget(timerEdt);
layout->addWidget(okBtn);
layout->addWidget(adviceEdt);
layout->addWidget(cancelBtn);
this->setWindowTitle("Advice");
this->setLayout(layout);
connect(okBtn,SIGNAL(clicked()), this, SLOT(setTimer()));
connect(cancelBtn, SIGNAL(clicked()), this, SLOT(cancelTimer()));
connect(timer, SIGNAL(timeout()),this, SLOT(displayAdvice()));
}
void Widget::setTimer()
{
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()),this, SLOT(cancelTimer()));
QString setting = this->timerEdt->text();
bool ok;
int set = setting.toInt(&ok,10);
set = set * 1000;
timer->setInterval(set);
timer->start();
timerEdt->setReadOnly(true);
okBtn->setDown(true);
}
void Widget::cancelTimer()
{
timer->stop();
adviceEdt->clear();
okBtn->setDown(false);
timerEdt->clear();
timerEdt->setReadOnly(false);
}
void Widget::displayAdvice()
{
process = new QProcess(this);
process->start("C:/Users/Dmon/Desktop/47039949 COS3711 Assignment 2/Question 4/Ass2Q4Part1-build-desktop/debug/Ass2Q4Part1.exe");
connect(process, SIGNAL(readyReadStandardOutput()),this, SLOT(addAdvice()));
connect(process, SIGNAL(finished(int)),this, SLOT(processDone(int)));
}
void Widget::addAdvice()
{
QByteArray data = process->readAllStandardOutput();
QString strToWrite = data;
this->adviceEdt->clear();
this->adviceEdt->append(strToWrite);
}
void Widget::processDone(int)
{
process->close();
process->deleteLater();
process=0;
}
main.cpp
#include <QtGui/QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
Program runs with nothing displayed then eventually exits with no errors after about 15 seconds.
Your problem is that you're already using a user interface coming from the form file (.ui file). You need to decide which one you wish to use.
To fix your code, all you need to do is remove all references to the Ui namespace. Simply remove the below:
namespace Ui {
class Widget;
}
//
private:
Ui::Widget *ui;
//
#include "ui_widget.h"
//
delete ui;
Also, note that this line is working with a null or undefined pointer value - you never create the timer instance:
connect(timer, SIGNAL(timeout()),this, SLOT(displayAdvice()));
Finally, there's no reason whatsoever to allocate the member widgets on the heap. It does, in fact, waste a bit of heap memory since QWidget instances are very small.
Here's how your code could look. I've put it all in a single file, to keep it short. You obviously don't need it in a single file. I've also made the UI a bit more compliant with usual expectations. E.g. controls that can't be interacted with should be disabled.
// main.cpp
#include <QApplication>
#include <QtWidgets>
#include <QTimer>
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
private slots:
void setTimer();
void displayAdvice();
void cancelTimer();
void addAdvice();
void processDone(int);
private:
QLabel m_timerLbl;
QLineEdit m_timerEdt;
QTextEdit m_adviceEdt;
QPushButton m_okBtn;
QPushButton m_cancelBtn;
QTimer m_timer;
QProcess m_process;
void setupGui();
};
Widget::Widget(QWidget *parent) :
QWidget(parent)
{
setupGui();
}
void Widget::setupGui()
{
m_timerLbl.setText("Timer set interval in seconds");
m_adviceEdt.setReadOnly(true);
m_okBtn.setText("OK");
m_cancelBtn.setText("Cancel");
m_cancelBtn.setEnabled(false);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(&m_timerLbl);
layout->addWidget(&m_timerEdt);
layout->addWidget(&m_okBtn);
layout->addWidget(&m_adviceEdt);
layout->addWidget(&m_cancelBtn);
setWindowTitle("Advice");
connect(&m_okBtn, SIGNAL(clicked()), SLOT(setTimer()));
connect(&m_cancelBtn, SIGNAL(clicked()), SLOT(cancelTimer()));
connect(&m_timer, SIGNAL(timeout()), SLOT(displayAdvice()));
connect(&m_timer, SIGNAL(timeout()), SLOT(cancelTimer()));
connect(&m_process, SIGNAL(readyReadStandardOutput()), SLOT(addAdvice()));
connect(&m_process, SIGNAL(finished(int)), SLOT(processDone(int)));
}
void Widget::setTimer()
{
QString const setting = m_timerEdt.text();
bool ok;
int set = setting.toInt(&ok,10) * 1000;
m_timer.setInterval(set);
m_timer.start();
m_timerEdt.setEnabled(false);
m_okBtn.setEnabled(false);
m_cancelBtn.setEnabled(true);
}
void Widget::cancelTimer()
{
m_timer.stop();
m_adviceEdt.clear();
m_timerEdt.clear();
m_okBtn.setEnabled(true);
m_timerEdt.setEnabled(true);
m_cancelBtn.setEnabled(false);
}
void Widget::displayAdvice()
{
m_process.start("bash", QStringList() << "-c" << "echo 'Hello!'");
#if 0
m_process.start(QDir::homePath() +
"/Desktop/47039949 COS3711 Assignment 2/Question 4/Ass2Q4Part1-build-desktop/debug/Ass2Q4Part1.exe");
#endif
}
void Widget::addAdvice()
{
QByteArray const data = m_process.readAllStandardOutput();
m_adviceEdt.setPlainText(QString::fromLocal8Bit(data));
}
void Widget::processDone(int)
{
m_process.close();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "main.moc"

Abnormal termination when calling `cvCreateCameraCapture(-1)`

My code as follow. When I execute cvCreateCameraCapture(-1) in openCamera, the app ends.
TIP: Abnormal program termination. during startup program exited with code 0X000135
Why? The computer is notebook, and inner-Camera.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
>
#include<highgui.h>
#include<cv.h>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void openCamera();
void readFrame();
void closeCamera();
void takingPhote();
private:
Ui::MainWindow *ui;
QTimer* timer;
QImage* image;
CvCapture* cam;
IplImage* frame;
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
cam = NULL;
timer = new QTimer(this);
image = new QImage;
connect(ui->openCamera, SIGNAL(clicked()), this, SLOT(openCamera()));
}
void MainWindow::openCamera()
{
cam = cvCreateCameraCapture(-1);
// timer->start(33);
// connect(timer, SIGNAL(timeout()), this, SLOT(readFrame()));
}
Adding my previous comment as an answer since it helped you solve the problem:
I want you to replace the cvCreateCameraCapture() call for something else, like cvWaitKey(0);. If this is a runtime issue related to environment variables and Windows not finding OpenCV, this simple test will show. So, if it continues to crash then it might really be related to the environment configuration.