在Qt主窗口关闭后如何返回信息?

时间:2014-08-06 15:53:39

标签: c++ qt

您好我是c ​​++的新手,我一直在尝试在Ubuntu上创建一个程序,该程序将在多个设备上获取Opengazer(凝视跟踪软件)的输出并返回单个坐标。这是通过为每个设备打开一个UDP套接字来完成的,然后将一个[Xcoordinate Ycoordinate]形式的文本输出发送到主程序,然后比较数字,然后输出正确的坐标。

我发现在Qt中创建一个gui是确定每个设备相对位置的最佳方法。基本上,我遇到的问题是将UDP套接字上的信息带回主程序。在getInfo函数中,我创建了一个主窗口,其中创建了我的设备(另一个名为DeviceWidget的类),并且可以移动它来设置它们的相对位置。每个DeviceWidget都有一个与之关联的UDP套接字。我希望在窗口关闭时返回所有DeviceWidgets的QList,但是我遇到了困难,因为当窗口关闭时,所有的子节点都被销毁了。我还读过按钮不能返回值,所以这也不起作用。

我发布了main.cpp和window.cpp。我可以发布更多,但我相信这是唯一必要的两个。

有什么想法吗?谢谢你的时间。

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;
}

2 个答案:

答案 0 :(得分:2)

嗯,我认为代码太多了,下次再尝试更简洁。 (如果你的画面尺寸为300x500或者其他什么,我们都不在乎:p)

我不喜欢你在这里做的事情:

PortDialog *pop = new PortDialog(this);
pop->exec();
int port = pop->getPort();

我认为您可以使用信号和插槽解决您的问题。在你的PortDialog中,当你想要获得一个值(计算,由用户编写,无论如何)时,你可以做你的东西,只需emit(sigPortValue(int val));

在你的void Window::on_addButton_pressed()函数中,你可以写

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();
    [...]
}

显然,处理上面提到的插槽中的端口值。这是第一点。

第二点是关于QList。为清楚起见,此QList<DeviceWidget*> getInfo(...)是一个返回QList副本的函数。一个QList是什么?指向DeviceWidget的指针。复制列表时,复制列表的内容(这里是指针),而不是指向的对象。并且因为您的DeviceWidgets将MainWindow作为父级,所以它们将被删除(您可以理解这一点!)。

我看到两个解决方案:

孤儿解决方案

您可以省略DeviceWidget *primary = new DeviceWidget(frame, 200, 200, 20230);,而不是编写frame,因此如果没有任何父级,则不会自动删除DeviceWidget。 请注意正确delete对象!

其他沟通方式

您可以将信息存储在文件中,而不是尝试直接在代码中传递信息,但您可以根据自己的需要查看最佳解决方案。

希望这会对你有帮助;)

答案 1 :(得分:0)

如果您的Window可以从QDialog派生,那么您可以使用QDialog::exec()在本地控制事件循环。

如果我正确理解了您的问题,以下内容似乎正在按照您的要求做一些事情:它显示QDialog一个QTextEdit,您可以在其中输入文字,一旦您关闭该主窗口的主要功能,显示QDialogQTextEdit获取信息并显示它。

这有帮助还是我误解了你的问题所在?

#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();
}