PDA

View Full Version : Instantiate the QApplication object first



Brixus
10th April 2014, 23:00
Hello,

I have a problem using QSerialPort.
If I try to set the serial connection parameters directly in the main I get the message:
QApplication::qAppName: Please instantiate the QApplication object first

If I try to solve this with adding line 3 in the code I get another error:
invalid conversion from 'const char**' to 'char**' [-fpermissive]

This is how the code looks:

int main( int argc, const char** argv)
{
QCoreApplication a(argc, argv);
serial.setPortName("/dev/usb0"); // The other configuration parameters follow...


What can I do to solve the problem?
The first line of the code should not be changed.
In the background is a bigger programm written by another person.
I just try to modify the opensource code for personal use.


Thank you very much :)

ChrisW67
11th April 2014, 00:29
The correct prototype for the C++ main() is one of:


int main(int argc, char *argv[]); // argv is not const
int main(int argc, char **argv); // direct equivalent of first option
int main(void);

The last option is not useful in most Qt programs because argc and argv are required by QCoreApplication. Notice that argv is not const and, indeed, Qt may modify it in the QApplication initialisation.

Provide a complete program that reproduces the first problem. This:


#include <QCoreApplication>
#include <QSerialPort>

int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QSerialPort serial;
serial.setPortName("/dev/ttyS0");
return app.exec();
}

works just fine here (Qt5.2.0 Linux). Your code does not show the declaration of "serial". If it is global and static then the problem could simply be that it is initialised (and fails) before main() is run.

Brixus
11th April 2014, 13:01
Thank you very much :-)

In the original code a command line parser was used.
As I do not really need this feature at the moment I removed it from the code.

The code below works if I delete the lines 72 to 79.

Otherwise I get a new error:

Cannot create a QWidget without QApplication

This is how the code looks:


#include <QCoreApplication>
#include <QSerialPort>

#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <iostream>
#include <ctype.h>

using namespace cv;
using namespace std;

QSerialPort serial;


Mat image;

bool backprojMode = false;
bool selectObject = false;
int trackObject = 0;
bool showHist = true;
Point origin;
Rect selection;
int vmin = 10, vmax = 256, smin = 30;

static void onMouse( int event, int x, int y, int, void* )
{
if( selectObject )
{
selection.x = MIN(x, origin.x);
selection.y = MIN(y, origin.y);
selection.width = std::abs(x - origin.x);
selection.height = std::abs(y - origin.y);

selection &= Rect(0, 0, image.cols, image.rows);
}

switch( event )
{
case CV_EVENT_LBUTTONDOWN:
origin = Point(x,y);
selection = Rect(x,y,0,0);
selectObject = true;
break;
case CV_EVENT_LBUTTONUP:
selectObject = false;
if( selection.width > 0 && selection.height > 0 )
trackObject = -1;
break;
}
}

static void help()
{
cout << "\nThis is a demo that shows mean-shift based tracking\n"
"You select a color objects such as your face and it tracks it.\n";


cout << "\n\nHot keys: \n"
"\tESC - quit the program\n"
"\tc - stop the tracking\n"
"\tb - switch to/from backprojection view\n"
"\th - show/hide object histogram\n"
"\tp - pause video\n"
"To initialize tracking, select the object with mouse\n";
}


int main( int argc, char *argv[])
{
QCoreApplication app(argc, argv);
serial.setPortName("/dev/rfcomm0");
serial.open(QIODevice::WriteOnly);
serial.setBaudRate(QSerialPort::Baud115200);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);

help();

VideoCapture cap(0);
Rect trackWindow;
int hsize = 16;
float hranges[] = {0,180};
const float* phranges = hranges;


if( !cap.isOpened() )
{
help();
cout << "***Could not initialize capturing...***\n";
return -1;
}

namedWindow( "Histogram", 0 );
namedWindow( "Demo", 0 );
setMouseCallback( "Demo", onMouse, 0 );
createTrackbar( "Vmin", "Demo", &vmin, 256, 0 );
createTrackbar( "Vmax", "Demo", &vmax, 256, 0 );
createTrackbar( "Smin", "Demo", &smin, 256, 0 );

Mat frame, hsv, hue, mask, hist, histimg = Mat::zeros(200, 320, CV_8UC3), backproj;
bool paused = false;

for(;;)
{
if( !paused )
{
cap >> frame;
if( frame.empty() )
break;
}

frame.copyTo(image);

if( !paused )
{
cvtColor(image, hsv, COLOR_BGR2HSV);

if( trackObject )
{
int _vmin = vmin, _vmax = vmax;

inRange(hsv, Scalar(0, smin, MIN(_vmin,_vmax)),
Scalar(180, 256, MAX(_vmin, _vmax)), mask);
int ch[] = {0, 0};
hue.create(hsv.size(), hsv.depth());
mixChannels(&hsv, 1, &hue, 1, ch, 1);

if( trackObject < 0 )
{
Mat roi(hue, selection), maskroi(mask, selection);
calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
normalize(hist, hist, 0, 255, CV_MINMAX);

trackWindow = selection;
trackObject = 1;

histimg = Scalar::all(0);
int binW = histimg.cols / hsize;
Mat buf(1, hsize, CV_8UC3);
for( int i = 0; i < hsize; i++ )
buf.at<Vec3b>(i) = Vec3b(saturate_cast<uchar>(i*180./hsize), 255, 255);
cvtColor(buf, buf, CV_HSV2BGR);

for( int i = 0; i < hsize; i++ )
{
int val = saturate_cast<int>(hist.at<float>(i)*histimg.rows/255);
rectangle( histimg, Point(i*binW,histimg.rows),
Point((i+1)*binW,histimg.rows - val),
Scalar(buf.at<Vec3b>(i)), -1, 8 );
}
}

calcBackProject(&hue, 1, 0, hist, backproj, &phranges);
backproj &= mask;
RotatedRect trackBox = CamShift(backproj, trackWindow,
TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ));
if( trackWindow.area() <= 1 )
{
int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5)/6;
trackWindow = Rect(trackWindow.x - r, trackWindow.y - r,
trackWindow.x + r, trackWindow.y + r) &
Rect(0, 0, cols, rows);
}



if( backprojMode )
cvtColor( backproj, image, COLOR_GRAY2BGR );
ellipse( image, trackBox, Scalar(0,0,255), 3, CV_AA );
serial.write("test/r/n"); //Here I want to use serial.write actions
serial.flush();
}
}
else if( trackObject < 0 )
paused = false;

if( selectObject && selection.width > 0 && selection.height > 0 )
{
Mat roi(image, selection);
bitwise_not(roi, roi);
}

imshow( "Demo", image );
imshow( "Histogram", histimg );

char c = (char)waitKey(10);
if( c == 27 )
break;
switch(c)
{
case 'b':
backprojMode = !backprojMode;
break;
case 'c':
trackObject = 0;
histimg = Scalar::all(0);
break;
case 'h':
showHist = !showHist;
if( !showHist )
destroyWindow( "Histogram" );
else
namedWindow( "Histogram", 1 );
break;
case 'p':
paused = !paused;
break;
default:
;
}
}
serial.close();
return app.exec();

}


And this is my .pro file:

QT += core serialport

QT -= gui

TARGET = Demo
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app


SOURCES += main.cpp

INCLUDEPATH += /usr/local/include/opencv
INCLUDEPATH += /usr/local/include/opencv2

LIBS += -L/usr/local/lib \
-lopencv_core \
-lopencv_imgproc \
-lopencv_highgui \
-lopencv_ml \
-lopencv_video \
-lopencv_features2d \
-lopencv_calib3d \
-lopencv_objdetect \
-lopencv_contrib \
-lopencv_legacy \
-lopencv_flann



What can I do to make it work?

Thank you very much :-)

Added after 1 16 minutes:

I found the solution by myself :-)

In the .pro file I added QT += widgets and in the main I included QApplication and replaced QCoreApplication by QApplication :-)