Hi I'm new to c++ and I've been trying to create a program on Ubuntu that will take the output of Opengazer (gaze tracking software) on multiple devices and return a single coordinate. This is done by opening a UDP socket for each device which then sends a a text output of the form [Xcoordinate Ycoordinate] to the main program where the numbers will then be compared and the correct coordinate will then be output.
I found that creating a gui in Qt was the best way to establish the relative positions of each device. Basically, the problem I am having is bringing the information on the UDP sockets back through to the main program. In the getInfo function, I create the main window where my devices (another class called DeviceWidget) are created and are movable to set their relative positions. Each DeviceWidget has a UDP socket associated with it. I would like to return a QList of all of the DeviceWidgets when the window closes, but I am having a difficult time because when the window closes, all of the children are destroyed. I have also read that buttons cannot return values so this will not work either.
I am posting main.cpp and window.cpp. I can post more but I believe these are the only two necessary.
Any ideas? Thank your for your time.
Main.cpp
#include <QApplication>
#include "window.h"
#include "devicewidget.h"
#include <QTimer>
QList<DeviceWidget*> getInfo(int argc, char *argv[]);
void delay();
int main(int argc, char *argv[])
{
bool run = true;
int numDevices, space, size;
DeviceWidget *point;
QList<DeviceWidget*> dList = getInfo(argc, argv);
numDevices = dList.size();
int xPos[numDevices], yPos[numDevices];
QString buffers[numDevices], xString, yString;
//begin tracking gaze
if(run)
{
for(int i=0; i<numDevices; i++)
{
//get output of opengazers
point = dList.at(i);
buffers[i] = point->Server->getBuffer();
space = buffers[i].indexOf(" ");
size = buffers[i].size();
xString = buffers[i].left(space);
yString = buffers[i].right(size-space-1);
xPos[i] = xString.toInt();
yPos[i] = yString.toInt();
}
//print coordinate
for(int i=0; i<numDevices; i++)
{
if((dList.at(i)->getXRes()/6<xPos[i]<dList.at(i)->getXRes()*5/6) && (dList.at(i)->getXRes()/4<xPos[i]<dList.at(i)->getXRes()*3/4))
{
qDebug() << xPos[i]+dList.at(i)->getXPos()*9-dList.at(0)->getXPos()*9 << " " << yPos[i]+dList.at(i)->getYPos()*9-dList.at(0)->getYPos()*9;
}
}
delay();
}
return 0;
}
QList<DeviceWidget*> getInfo(int argc, char *argv[])
{
QApplication a(argc, argv);
Window w;
w.show();
a.exec();
return w.getList();
}
void delay()
{
QTime dieTime= QTime::currentTime().addSecs(1);
while( QTime::currentTime() < dieTime )
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
window.cpp
#include "window.h"
#include <QFrame>
#include <QPushButton>
#include <QVBoxLayout>
#include <devicewidget.h>
#include <QWidget>
#include <QDesktopWidget>
#include <QList>
#include "portdialog.h"
#include "udp.h"
Window::Window(QWidget *parent) :
QWidget(parent),
frame(new QFrame(this)),
addButton(new QPushButton("Add Device", this)),
doneButton(new QPushButton("Done", this))
{
QVBoxLayout *layout = new QVBoxLayout;
frame->setLineWidth(2);
frame->setFrameStyle(QFrame::Box | QFrame::Plain);
QPoint topLeft(0,0);
QPoint bottomRight(100,100);
const QRect rect(topLeft, bottomRight);
frame->setFrameRect(rect);
frame->setFixedHeight(300);
frame->setFixedWidth(500);
layout->addWidget(frame);
layout->addWidget(addButton);
layout->addWidget(doneButton);
setLayout(layout);
connect(addButton, SIGNAL(released()), this, SLOT(on_addButton_pressed()));
connect(doneButton, SIGNAL(released()), this, SLOT(on_doneButton_pressed()));
DeviceWidget *primary = new DeviceWidget(frame, 200, 200, 20230);
primary->setFixedHeight(getResolutionY()/10);
primary->setFixedWidth(getResolutionX()/10);
primary->show();
primary->move(200,200);
list.append(primary);
}
void Window::on_addButton_pressed()
{
//pop-up for port
PortDialog *pop = new PortDialog(this);
pop->exec();
int port = pop->getPort();
/*int xRes = pop->getXRes();
int yRes = pop->getYRes();*/
int xRes = 1360;
int yRes = 760;
//create and show widget
DeviceWidget *secondary = new DeviceWidget(frame, 200, 200, port);
secondary->createServer(port, xRes, yRes);
secondary->setFixedHeight(secondary->getYRes() / 9);
secondary->setFixedWidth(secondary->getXRes() / 9);
secondary->show();
secondary->move(200,200);
list.append(secondary);
}
void Window::on_doneButton_pressed()
{
this->close();
}
int Window::getResolutionX()
{
QDesktopWidget widget;
QRect mainScreenSize = widget.availableGeometry(widget.primaryScreen());
return mainScreenSize.width();
}
int Window::getResolutionY()
{
QDesktopWidget widget;
QRect mainScreenSize = widget.availableGeometry(widget.primaryScreen());
return mainScreenSize.height();
}
QList<DeviceWidget*> Window::getList()
{
return list;
}
Well, that's too much code I think, next time, try to be more concise. (We don't care if your frame has a size of 300x500 or whatever :p)
I dislike what you did here:
PortDialog *pop = new PortDialog(this);
pop->exec();
int port = pop->getPort();
I think you can overcome your problem using signal and slots. In your PortDialog, you do your stuff, when you want to get a value (computed, written by user, whatever), you just emit(sigPortValue(int val));
And in your void Window::on_addButton_pressed()
function, you could write
void Window::on_addButton_pressed()
{
//pop-up for port
PortDialog *pop = new PortDialog(this);
connect(pop, SIGNAL(sigPortValue(int), this, SLOT(slotHandlePortValue(int));
pop->exec();
[...]
}
and obviously, handling the port value in the slot just mentionned above. So that's the first point.
The second point was about QList. To be clear, this QList<DeviceWidget*> getInfo(...)
is a function which returns a copy of a QList. A QList of what ? Of pointers to DeviceWidget. When you copy a list, you copy the content of the list (so pointers here) but not objects pointing at. And because your DeviceWidgets has the MainWindow as a parent, they are deleted (You correclty understood that !).
I see two solutions:
orphan solution
Instead of writing DeviceWidget *primary = new DeviceWidget(frame, 200, 200, 20230);
, you can omit frame
, so without any parent, the DeviceWidget will not be deleted automatically. Pay attention to correctly delete
the object though !
other communication way
Instead of trying to communicate information directly in the code, you can store information in a file, but it's up to you to see what's the best solution for your needs.
Hope this will help you ;)
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments