How can I get information back after closing my main window in Qt?

Hi I am new to C ++ and I am trying to create a program on Ubuntu that will display the output of the Opengazer software (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 text output of the form [Xcoordinate Ycoordinate] to the main program, where the numbers will be compared and then the correct coordinate will be printed.

I found that creating a gui in Qt is the best way to set the relative positions of each device. Basically, the problem I ran into was getting the UDP socket information to the main program. In the getInfo function I create a main window in which my devices (another class called DeviceWidget) are created and can be navigated to set their relative positions. Each DeviceWidget has a UDP socket associated with it. I would like to return a QList of all DeviceWidgets when the window is closed, but I find it difficult because when the window is closed, all children are destroyed. I also read that buttons cannot return values, so that won't work either.

I am posting main.cpp and window.cpp. I can post more, but I believe these are the only ones that are needed.

Any ideas? Thank you 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;
}

      

+3


source to share


2 answers


It's a good thing too much code, I think next time I'll try to be more concise. (We don't care if your frame is 300x500 or whatever: p)

I don't like 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, user written, whatever) you justemit(sigPortValue(int val));

And in your function, void Window::on_addButton_pressed()

you can 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 discussed above. So the first point.



The second point was about QList. To be clear, this QList<DeviceWidget*> getInfo(...)

is a function that returns a copy of a QList. QList about what? Pointers to DeviceWidget. When you copy a list, you are copying the contents of the list (as you specify here), but you are not specifying objects. And since your DeviceWidgets have a MainWindow as a parent, they are removed (you got that right!).

I see two solutions:

orphan decision

Instead of writing, DeviceWidget *primary = new DeviceWidget(frame, 200, 200, 20230);

you can omit frame

, so without any parent the DeviceWidget won't be automatically deleted. Pay attention to the correct delete

object though!

another way of communication

Instead of trying to pass information directly in code, you can store the information in a file, but it's up to you to decide which is the best solution for your needs.

Hope this helps you;)

+2


source


If your Window can be retrieved from a QDialog, you can use it QDialog::exec()

to control the event loop locally.

If I understand your question correctly, it seems that you are doing something similar to what you are asking: it shows QDialog

with QTextEdit

which you can enter text, and as soon as you close that window, the main function just continues, shows QDialog

which gets information from QTextEdit

and displays it.



Does this help or am I misunderstanding where your problem is?

#include <QApplication>
#include <QDialog>
#include <QGridLayout>
#include <QTextEdit>
#include <QPushButton>
#include <QLabel>

int main(int argc, char** argv)
{
  QApplication app(argc,argv);

  // show a dialog that lets you enter text                                                                                                                                
  QDialog dialog;
  QGridLayout layout(&dialog);
  QTextEdit edit;
  layout.addWidget(&edit);

  // this will block until the window is closed                                                                                                                            
  dialog.exec();

  // open a new dialog....                                                                                                                                                 
  QDialog closeMe;
  QGridLayout layout2(&closeMe);
  QLabel label;
  // ... retrieve the text from the dialog we created first                                                                                                                
  label.setText(QObject::tr("You entered: ")+edit.toPlainText());
  QPushButton button("Click here to close application");

  layout2.addWidget(&label,0,0);
  layout2.addWidget(&button,1,0);
  QObject::connect( &button, SIGNAL( clicked() ), &closeMe, SLOT( accept() ) );

  closeMe.show();
  return app.exec();
}

      

0


source







All Articles