Passing data to Qdialog
-
Hi everyone! I`m quite new working with Qt. I have been trying to make a GUI to collect datas from a COM Port (Serial Port). In the MainWindow are the buttons which once clicked should open a second window (QDialog) and display the datas in some lineEdit. For some reason the datas are not been displayed . I appreciate if someone could help me with it. Thanks in advance.
mainwindow.cpp
@#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "windowactualdata.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QMessageBox>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QKeyEvent>WindowActualData *ActualDataWindow;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);serial = new QSerialPort(this); foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { ui->PortDefinitionMain->addItem(info.portName()); } connect(serial, SIGNAL(readyRead()), this, SLOT(readData())); ui->Button_ConnectMain->setEnabled(true); //Enabled Connect button to be pressed initActionsConnections(); connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(handleError(QSerialPort::SerialPortError)));
}
MainWindow::~MainWindow()
{
delete ui;
}void MainWindow::on_Button_ActualDataMain_clicked()
{
//Open the "Actual Data" Window
WindowActualData WindowActualDataObject;
WindowActualDataObject.setModal(true);
WindowActualDataObject.exec();
}void MainWindow::initActionsConnections()
{
connect(ui->Button_ConnectMain, SIGNAL(clicked()), this, SLOT(openSerialPort())); // Call the openSerialPort()
}void MainWindow::openSerialPort()
{
pname = ui->PortDefinitionMain->currentText();serial->setPortName(pname); serial->setBaudRate(QSerialPort::Baud19200); serial->setDataBits(QSerialPort::Data8); serial->setParity(QSerialPort::NoParity); serial->setStopBits(QSerialPort::OneStop); serial->setFlowControl(QSerialPort::NoFlowControl); if (serial->open(QIODevice::ReadWrite)) { ui->Button_ConnectMain->setEnabled(false); ui->statusBar->showMessage(tr("Connected to %1") //Display the serial is connected .arg(pname)); } else { //Open Message Box: "Error" QMessageBox::critical(this, tr("Error"), serial->errorString()); ui->statusBar->showMessage(tr("Open error")); //Display "Open error" }
}
void MainWindow::readData()
{
if (serial->canReadLine()) {
QString data = serial->readLine();qDebug() << data; ActualDataWindow = new WindowActualData(this); QString y = data.mid(0,2); if (y == "Up"){ QString x = data.mid(5,5); qDebug()<< x; ActualDataWindow->UpdateActualData(x); } }
}
void MainWindow::writeData(const QByteArray &data) //Read data
{
serial->write(data);
}void MainWindow::handleError(QSerialPort::SerialPortError error) //Message Box "Error"
{
if (error == QSerialPort::ResourceError) {
QMessageBox::critical(this, tr("Critical Error"), serial->errorString());
closeSerialPort();
}
}void MainWindow::closeSerialPort()
{
serial->close();
ui->Button_ConnectMain->setEnabled(true);
}//Key Event
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if(event->key()=='A'|| event->key()=='a')
{
WindowActualData WindowActualDataObject;
WindowActualDataObject.setModal(true);
WindowActualDataObject.exec();
}
}@windowactualdata.cpp
@#include "windowactualdata.h"
#include "ui_windowactualdata.h"
#include "mainwindow.h"WindowActualData::WindowActualData(QWidget *parent) :
QDialog(parent),
ui(new Ui::WindowActualData)
{
ui->setupUi(this);
}WindowActualData::~WindowActualData()
{
delete ui;
}void WindowActualData::UpdateActualData(const QString &x)
{
QString value = x;
ui->lineEditData->setText(value);
}@ -
Hi,
The dialog you open when the button is clicked is not the one you set the data to. You should have a single instance of that dialog and set data to that single instance.
On the other hand, whenever new data is available you create a new instance of the dialog. You don't need to do that. As I said above, have a single instance of that dialog. You can call exec() on that instance when necessary.
-
like ckakman tell you, each time you call a nex instance of the dialogbox... so if you want to let this, youy have to access datas in a same place from inside the dialogbox (or do what ckakman tell you to do).
for have a data space there is many ways...write them in a file and access this file from dialogbox
write them in a database and read it from dialogbox
create a singleton class and static datas for access them from every where
call dailogbox with arguments contain your datas (bring them in a QHas or other... and push them in args at call time)
make a pointer on a "data container" and push it in args at dialogbox call time (who is maybe what you want to do)
not use a dialogbox, but maybe a tooltip to be refresh or an other widget, or some other ways...
-
which exemple you would like to follow ?
my reflexion, also, was to a suggestion around the fact that maybe use a QDialog box only for show little datas (but i don't know... are ther big or not ?) is maybe not the easy way. I talk about some other way like "toolTip" display for little datas... toolTip is a little mini-window popup when yuor mouse stay onside a widget. this can embed your data design by the widget the mouse is on (for exemple). I use it many time because i have a lot of differents data to show.this one ckrakman tell you is:
to not define (in mainwindow.h file) the dialogbox, but after that, to create only one object to call. Like:
@
#include "windowactualdata.h"
// and at private place of your class definition part:
windowsactualdata *my_dialog;
@after, when you need to call it, you can just do (in your maninwindow.cpp):
@
// inside the constructor directly, create your dialogbox:
my_dialog = new windowactualdata(this,data);// and call it from where you need after and wher you want:
my_dialog->exec()
@but if you want to bring datas inside this dialogBox, you need to pass an arg (if you choose this way).
So.... you need to define it with args you want to pass trough.
for exemple (in the cpp file of your dialogBox):@
WindowActualData::WindowActualData(QWidget *parent,
QString my_string) :
QDialog(parent),
ui(new Ui::WindowActualData)
{
ui->setupUi(this);
QString data = my_string;
}@
in the .h file of your dialogbox, you need to indicate it (and maybe also to define a default value in case of you not pass the data):
@
class WindowActualData : public QDialog
{
Q_OBJECTpublic:
explicit WindowActualData(QWidget *parent = 0,
QString my_string = "");
@but this is a simple exemple and you can pass Object you want or better more... is to pass a constant pointer to the data you want to read. Like that each time the data change the pointer stay the same and also you will not use more memory space for redundant datas.
you can choose to put the data inisde the container you want (and point on it)...
depend of your form of data to be handled. you can use also a struct form of content and make a pointer on it. But this is C++ and not Qt.
Qt have some other container for datas... like QHash, QMap, and QVariant, QList... you can also combine them like: QList<QVariant> or QHash<QString, QList<QVariant> >. But this is a choice you have to do depend of the form of your datas and what you need to use them later.in fact, the way of bring data at call time is just C++ code. Qt is just some special tools added to the C++ style of coding.
I'm new on Qt and C++ too.. (3 months i code it), but you can see many different exemples teach this in the web. Yuo maybe have better way to search first C++ information around this, and then, look at Qt if you can use a tool for make it with.
i hope i answer your question, but maybe you need to precise the choice you want to do first.
-
also... for your need, i think this exemple could be use:
//this is a form of QHash data with a pointer to pass to your dialogbox
@
class MainWindow : public QMainWindow, Ui::MainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QHash<QString, int> *my_hash_data;
@and then your definition of dialogbox class has to bring a QHash<QString, int> pointer...
in your .h file of your dialogbox:
@
class WindowActualData : public QDialog
{
Q_OBJECTpublic:
explicit WindowActualData(QWidget *parent = 0,
QHash<QString, int> *hash);
@sorry, but... it is a little bit difficult for me to use this editor from the forum...
-
Please compare the MainWindow::readData() function where you get the data and set the data to a new window on the heap but doesn't open that window by calling exec(), and the MainWindow::keyPressEvent(QKeyEvent *event) function where you open a brand new window on the stack which is not set any data. These are not the same window objects. This is the first issue.
The second issue is that you create a new window every time you have new data. Don't do that. Create a single instance, e.g., in the constructor and use that single instance to show data.