Signal-slot connection. The process was ended forcefully - qt

Here below are my codes on signal-slot connection demo:
Mainwindow.cpp (it receives signal data from Sender.cpp shown next)
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
status = false; //bool status
check = 0; //int check
sender = new Sender(); //Sender *sender
}
MainWindow::~MainWindow()
{
delete ui;
if(sender!=NULL)
{
delete sender;
}
}
void MainWindow::on_pushButton_clicked() //a pushbutton is created in mainwindow.ui
{
if(sender==NULL)
{
sender = new Sender();
}
if(status==false)
{
qDebug()<<"Button pressed.";
connectionStarter(); //Signal-slot connection is triggered here!
}
}
void MainWindow::connectionStarter()
{
connect(sender,SIGNAL(sendData(int)),this,SLOT(workSlot(int)),Qt::QueuedConnection);
}
void MainWindow::workSlot(int data)
{
this->data = data;
check++;
if(check!=60)
{
qDebug()<<"connected. check="<<check;
qDebug()<<"received data="<<this->data;
}
else
{
check=0;
status = true;
disconnect(sender,SIGNAL(sendData(int)),this,SLOT(workSlot(int)));
qDebug()<<"Disconnected.";
}
}
Sender.cpp (for signal generation, controlled with a QTimer object)
#include "sender.h"
Sender::Sender(QObject *parent) : QObject(parent)
{
data = 0; //data to be updated and transmitted
timer = new QTimer(this); //QTimer *timer
timer->setInterval(1000);
timer->start();
qDebug()<<"Timer started.";
connect(timer,SIGNAL(timeout()),this,SLOT(timerHandler()),Qt::DirectConnection);
}
void Sender::timerHandler()
{
data++; //int data
emit sendData(data);
qDebug()<<"Data emited.";
}
When I run the program, it has unexpectedly finished. The process was ended forcefully. Anyone can help debug my codes? Thanks!

Related

QT error when emit a signal from a function

I have a program that communicate with serial port.I dont want to use readyRead Signal I want to emit dataReceived signal when bytes come from serial, this signal connect to a slot to parse packet, but when I emit a Signal from reading Thread I have a error
the code is:
commSer.h:
#ifndef COMMSERIAL_H
#define COMMSERIAL_H
#include<QtSerialPort>
#include"fileaccess.h"
#include <QtCore/qglobal.h>
#include<QThread>
class CommSerial:public QThread
{
private:
QSerialPort *skt;
QString portName;
bool serialPortIsOepn;
FileAccess *file;
void initSkt();
void openPort();
signals:
void dataReceived(QByteArray);
public slots:
void writeToFile(QString);
void sendTo(QString);
void recievePacket(QByteArray);
public:
CommSerial();
~CommSerial();
bool stopReading;
void run(void);
QSerialPort* getPort(void);
};
#endif // COMMSERIAL_H
comSer.cpp
#include "commserial.h"
void CommSerial::initSkt()
{
skt=new QSerialPort();
portName="com3";
skt->setPortName(portName);
skt->setBaudRate(QSerialPort::Baud9600);
skt->setDataBits(QSerialPort::Data8);
skt->setParity(QSerialPort::NoParity);
skt->setStopBits(QSerialPort::OneStop);
skt->setFlowControl(QSerialPort::NoFlowControl);
connect(this,SIGNAL(dataReceived),this,SLOT(recievePacket()));
}
#include<QDebug>
void CommSerial::openPort()
{
if(skt->isOpen())
{
skt->close();
}
try {
skt->open(QIODevice::ReadWrite);
serialPortIsOepn=true;
} catch (const std::exception& ex) {
qDebug()<<"Erorr in :"<<ex.what();
serialPortIsOepn=false;
}
}
void CommSerial::writeToFile(QString str)
{
if(file->isOpen)
{
//QByteArray ba=QByteArray::fromStdString( str.toStdString());
//file->writeToFile(ba);
file->writeToFile(str);
}else {
qDebug()<<"serial port is not open";
}
}
void CommSerial::sendTo(QString str)
{
if(serialPortIsOepn)
{
QByteArray ba=QByteArray::fromStdString(str.toStdString());
skt->write(ba);
}else {
qDebug()<<"serial port is not open now";
}
}
void CommSerial::recievePacket(QByteArray ba)
{
QByteArray recBa=ba;
}
CommSerial::CommSerial()
{
stopReading=false;
serialPortIsOepn=false;
file=new FileAccess("d:/logSerial.txt");
file->openFile();
initSkt();
openPort();
}
CommSerial::~CommSerial()
{
skt->close();
file->~FileAccess();
}
void CommSerial::run()
{
while(!stopReading)
{
if(!skt->waitForReadyRead())
{
qDebug()<<"Serial Port has been closed";
stopReading=true;
break;
}
if(skt->bytesAvailable()>0)
{
QByteArray recBa=skt->readAll();
emit dataReceived(recBa); // this line has a error
}
msleep(100);
}
}
QSerialPort* CommSerial::getPort()
{
return skt;
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
skt=new CommSerial();
connect(skt->getPort(),SIGNAL(dataReceived()),this,SLOT(showRecievdData()));
}
errors:
error: undefined reference to `CommSerial::dataReceived(QByteArray)'
collect2.exe:-1: error: error: ld returned 1 exit status
The Q_OBJECT macro is missing
Notice that the Q_OBJECT macro is mandatory for any object that implements signals, slots or properties. You also need to run the Meta Object Compiler on the source file. We strongly recommend the use of this macro in all subclasses of QObject regardless of whether or not they actually use signals, slots and properties, since failure to do so may lead certain functions to exhibit strange behavior.

Qt thread makes the Qt Creator no respond for a while

I have a simple project on the demo of QThread using QtCreator4.5 and Qt5.7. In the project, three pushbuttons, threadA, threadB and quit, are created. My intention is to print A and B in the console when the threadA and threadB are clicked respectively, and the application is to be quitted when 'quit' is pressed.
Here is mythread.h:
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QString>
class mythread : public QThread
{
Q_OBJECT
public:
mythread();
void setMessage(const QString &message);
void stop();
protected:
void run();
private:
QString messageStr;
volatile bool stopped;
};
#endif // MYTHREAD_H
The mythread.cpp:
#include "mythread.h"
#include <iostream>
mythread::mythread()
{
stopped = false;
}
void mythread::setMessage(const QString &message)
{
messageStr = message;
}
void mythread::stop()
{
stopped = true;
}
void mythread::run()
{
while(!stopped)
std::cout<<qPrintable(messageStr);
stopped = false;
std::cout<< std::endl;
}
The mainwindow.cpp is:
#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_threadA_clicked()
{
mythreadA.start();
mythreadA.setMessage("A");
}
void MainWindow::on_threadB_clicked()
{
mythreadB.start();
mythreadB.setMessage("B");
}
void MainWindow::on_quit_clicked()
{
mythreadA.stop();
mythreadB.stop();
MainWindow::close();
}
When I run the project, the printed results are displayed in the Application Output of the QtCreator, not in an external prompt console. Quitting the application makes QtCreator no respond for a while, but finally restore to normal. It seems that the threads are still running when the application is quitted.
I have tested your code and there is nothing wrong with Qt Creator that is not frozen.
However, as your code is written, your threads are probably still running when you quit the application. Moreover, the private member stopped should be protected by a mutex, as volatile won't do this job.
To protect your private variable stopped with a mutex, you can use for example QMutexLocker in the following way :
void MyThread::stop() // called by the GUI Thread
{
const QMutexLocker locker(&m_mutex);
stopped = true;
}
and to read the value of the boolean :
bool MyThread::isStopped // called by run()
{
const QMutexLocker locker(&m_mutex);
return stopped;
}
Finally to ensure that the threads are properly finished when you press the quit button :
void MainWindow::on_quit_clicked()
{
mythreadA.stop();
mythreadB.stop();
myThreadA.wait();
myThreadB.wait();
this->close(); // close the main application
}

QEventLoop discard some signal

I have a question about QEventLoop: how to set a QEventLoop to discard some signal
class MyThread : public QThread
{
Dialog *_dlg;
public:
MyThread(Dialog* dlg)
: _dlg(dlg)
{
}
virtual void run()
{
QTimer* _timer;
_timer = new QTimer(this);
connect(_timer, SIGNAL(timeout()),
_dlg, SLOT(timeout()), Qt::BlockingQueuedConnection);
_timer->start(3000);
QEventLoop loop;
loop.exec(QEventLoop::WaitForMoreEvents);
}
};
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
connect(ui->pushButton, SIGNAL(clicked()),
this, SLOT(click()));
MyThread* thread = new MyThread(this);
thread->start();
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::click()
{
QMessageBox msgBox(this);
msgBox.setText("click.");
msgBox.exec();
}
void Dialog::timeout()
{
QMessageBox msgBox(this);
msgBox.setText("timeout.");
msgBox.exec();
}
this is my code when start this programe , every 5 second a timeout QMessageBox will be show .
but i want if i press button then show the click messagebox and do not show the timeout messagebox..
i failed to find any method to do it

QMessagebox not show text when call show()

my problem is I need to show a message ask users wait when I check network availability of other clients.My way is I have a class workerThread to do the business, before start it I create a qMessageBox. But the message only shows the title, not the content. I have no idea why, pls help :(
Here's the worker thread:
#include <QObject>
#include <QString>
#include "clientdataobj.h"
class WorkerThread : public QObject
{
Q_OBJECT
public:
explicit WorkerThread(QObject *parent = 0);
QList<ClientDataObj> listClient() const;
void setListClient(const QList<ClientDataObj> &listClient);
signals:
void finished();
void error(QString err);
void listClientPingChecked( QList <ClientDataObj> list);
public slots:
void testPing();
private:
QList <ClientDataObj> mListClient;
bool pingEachClient(QString ip);
};
implement:
#include "workerthread.h"
#include <QFile>
#include <QMessageBox>
#include <QTextStream>
WorkerThread::WorkerThread(QObject *parent) :
QObject(parent)
{
}
void WorkerThread::testPing()
{
if (mListClient.size()==0) {
emit finished();
return;
}
else{
for(unsigned i=0;i<mListClient.size();i++){
bool result = pingEachClient(mListClient[i].ip());
if(result)
mListClient[i].setStatus(true);
else
mListClient[i].setStatus(false);
}
emit listClientPingChecked(mListClient);
}
emit finished();
}
bool WorkerThread::pingEachClient(QString ip)
{
QString pingCommand = "ping " +ip + " -c 3 | grep loss | awk ' {print $7}' > pingResult.txt";
system(qPrintable(pingCommand));
QString lossPercentTxt = readFileText("pingResult.txt") ;
lossPercentTxt.chop(1);
int lossPercent = lossPercentTxt.toInt();
if(lossPercent<10){
return true;
}
else return false;
}
QList<ClientDataObj> WorkerThread::listClient() const
{
return mListClient;
}
void WorkerThread::setListClient(const QList<ClientDataObj> &listClient)
{
mListClient = listClient;
}
How I call it in MainWindow:
on_pbSendUpdate_clicked()
{
changeModeWaitPing();
getClientOnlineList();
}
getClientOnlineList()
{
if(mListClient.size()==0){
return;
}
mpThreadPing = new QThread;
mpWorkerThread = new WorkerThread;
mpWorkerThread->setListClient(mListClient);
connectThreadPingToGui();
mpThreadPing->start();
}
changeModeWaitPing()
{
ui->pbSendUpdate->setEnabled(false);
callMsgBox("Pinging client... Pls wait!");
// callWaitDialog();
}
callMsgBox( QString text)
{
if (NULL==mMsg) {
return;
}
mMsg->setWindowTitle("INFO");
// mMsg->setAttribute(Qt::WA_DeleteOnClose);
mMsg->setWindowModality(Qt::NonModal);
mMsg->setModal(false);
QString info ="Pinging client... Pls wait!";
mMsg->setText(info);
mMsg->show();
}
connectThreadPingToGui()
{
connect(mpWorkerThread, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(mpThreadPing, SIGNAL(started()), mpWorkerThread, SLOT(testPing()));
connect(mpWorkerThread, SIGNAL(finished()), mpThreadPing, SLOT(quit()));
connect(mpWorkerThread, SIGNAL(finished()), mpWorkerThread, SLOT(deleteLater()));
connect(mpThreadPing, SIGNAL(finished()), mpThreadPing, SLOT(deleteLater()));
connect(mpWorkerThread,SIGNAL(listClientPingChecked(QList<ClientDataObj>)),this,SLOT(updateListClientOnline(QList<ClientDataObj>)));
}
updateListClientOnline(QList<ClientDataObj> list)
{
mListClientOnline = list;
mPingDone = true;
if (NULL==mMsg) {
return;
}
else{
mMsg->hide();
}
if(mpDialogWaitPing==NULL){
return;
}
else{
mpDialogWaitPing->hide();
}
launchClientListTable();
}
You create a new thread, but you don't move any objects to that thread. So your new thread does nothing. I assume you wan't mpWorkerThread to be moved to the new thread. In that case you're missing mpWorkerThread->moveToThread(mpThreadPing);

how to calculate speed by gps data in qt mobility?

How I can get my speed, and distance by using gps data in qt?
I have such class, maybe is any standart method?
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "quitdiallog.h"
#include <QGeoCoordinate>
#include <QDebug>
#include <QtGui/QMessageBox>
#include <QList>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
setWindowTitle("Мой кОмпаС");
ui->setupUi(this);
startGPS();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::startGPS()
{
// Obtain the location data source if it is not obtained already
if (!locationDataSource)
{
locationDataSource =
QGeoPositionInfoSource::createDefaultSource(this);
if (locationDataSource)
{
// Whenever the location data source signals that the current
// position is updated, the positionUpdated function is called.
QObject::connect(locationDataSource,
SIGNAL(positionUpdated(QGeoPositionInfo)),
this,
SLOT(positionUpdated(QGeoPositionInfo)));
// Start listening for position updates
locationDataSource->setUpdateInterval(200);
locationDataSource->startUpdates();
} else {
// Not able to obtain the location data source
// TODO: Error handling
}
} else {
// Start listening for position updates
locationDataSource->setUpdateInterval(5000);
locationDataSource->startUpdates();
}
}
void MainWindow::positionUpdated(QGeoPositionInfo geoPositionInfo)
{
if (geoPositionInfo.isValid())
{
//locationDataSource->stopUpdates();
QGeoCoordinate geoCoordinate = geoPositionInfo.coordinate();
this->latitude = geoCoordinate.latitude();
this->longitude = geoCoordinate.longitude();
this->altitude=geoCoordinate.altitude();
ui->label->setNum(latitude);
ui->label_2->setNum(longitude);
}
}
void MainWindow::on_pushButton_clicked()
{
ui->label_3->setNum(latitude);
qDebug()<<latitude<<" "<<longitude<<" "<<altitude;
}
void MainWindow::on_pushButton_4_clicked()
{
QuitDiallog *qi=new QuitDiallog;
this->hide();
qi->show();
}
How to get speed???
first i would do source->setPreferredPositioningMethods(QGeoPositionInfoSource::AllPositioningMethods);
The groundspeed can be fetched (theoretically) by geoPositionInfo.attribute(QGeoPositionInfo::GroundSpeed)
But be sure that geoPositionInfo.hasAttribute(QGeoPositionInfo::GroundSpeed) == true
AFAIK there are some issues with groundspeed on several mobile devices.

Resources