PDA

View Full Version : One dialog for several lcdnumber values?



ssaguiar
25th April 2011, 22:23
Hi to all

This is my first post, so, pleas, be gently.

I am writing a test code for an application where I willl read data for 4 to 16 water tanks and present the values of these in several lcd numbers in the main window.
If the user click on one image (one for each of the lcd numbers because the lcd numbers don't have the onclick event), I need to show a new window (in this case I have one QDialog), with the present tank value and a graphic with the last readings.

The problem i sthat I have to create one QDialog for each of the tanks because the slot() don't accept a value in it's call.

Can somebody explain, if possible, how can I create just one QDialog and pass a variable value to it, wich is the index of the tank, so I can read the log file and plot the data?

This is my present source code. I have mixed some C++ and C propositaly because I want to minimise the use of libs becaus ethis app will run in a Arm based board, with a 7 inch display (mini2440).:



#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.showMaximized();
return a.exec();
}


dialog1.cpp:


#include "mainwindow.h"
#include <dialog1.h>

Dialog::Dialog( QWidget* Parent, Qt::WFlags Flags ) : QDialog( Parent, Flags )
{
setWindowTitle( tr( "Tanque 1" ) );
resize( QSize(800, 480).expandedTo(minimumSizeHint()) );
setWindowFlags(this->windowFlags() & Qt::Window | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
this->setStyleSheet( "background-image: url(:/images/background_main.png)");

QPushButton *Button = new QPushButton( tr( "ok" ), this );
QLCDNumber *Tanque1Level = new QLCDNumber(5, this);

Tanque1Level->setGeometry( 10, 10, 180, 80 );
Tanque1Level->setSmallDecimalPoint( false );
Tanque1Level->setNumDigits( 5 );
Tanque1Level->setSegmentStyle(QLCDNumber::Flat);
Tanque1Level->setFrameShape(QLCDNumber::Box);
Tanque1Level->setFrameShadow(QLCDNumber::Sunken);
Tanque1Level->setMode(QLCDNumber::Dec);
Tanque1Level->setStyleSheet("background: transparent;color:rgb(0,255,0); border: 2px solid grey;");
Tanque1Level->display(12976);

Button->setGeometry( QRect( 750, 440, 40, 30 ) );
connect( Button, SIGNAL( clicked() ), this, SLOT( close() ) );

}


dialog1.h:


#include <QDialog>
#include <QPushButton>

class Dialog : public QDialog
{
Q_OBJECT

public:
Dialog( QWidget* parent = 0, Qt::WFlags Flags = 0 );
~Dialog() {};

private:
QPushButton *Button;

};


mainwindow.h:



#ifndef MAINWINDOW_H
#define MAINWINDOW_H


#define CR 13
#define TIMEOUT_SERIAL 100
#define TIMETOCHKSER 1000 // Check serial every TIMETOCHKSER ms
#define TIMETOCREATELOG 3600000 // TIMETOCREATELOG ms, entre logs
#define MAX_BUFF_LEN 1024
#define BAUDRATE B9600
#define FUELTANKCAP 15000


#include "ui_mainwindow.h"

#include <QMainWindow>
#include <QtGui/QApplication>
#include <QPushButton>
//#include <QProgressBar>
#include <QDesktopWidget>
#include <QTimer>
#include <QString>
#include <QMessageBox>
#include <QLatin1String>
#include <QLCDNumber>
#include <QMainWindow>
#include <QDockWidget>

#include <qdir.h>

#include <sys/io.h>
#include <sys/time.h>
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>


namespace Ui {
class MainWindow;
}


class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
FILE *sfPtr;
FILE *flog; // Log File descriptor
bool CreateLogFile;
int screenWidth, width;
int screenHeight, height;
int x, y, TankIndex;
QSize windowSize;
~MainWindow();

private slots:
void updateSerialData(void);
void EnableLog(void);
void View_tank1_Details(void);
void View_tank2_Details(void);
void View_tank3_Details(void);
void View_tank4_Details(void);
void View_tank5_Details(void);
void View_tank6_Details(void);
void View_tank7_Details(void);
void View_tank8_Details(void);
void View_tank9_Details(void);
void View_tank10_Details(void);
void View_tank11_Details(void);
void View_tank12_Details(void);
void View_tank13_Details(void);
void View_tank14_Details(void);
void View_tank15_Details(void);
void View_tank16_Details(void);
void View_tank_Details(int index);
void dialog();
private:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H


test1.pro:


QT += core gui

TARGET = test1
TEMPLATE = app

DEFINES = _TTY_POSIX_

SOURCES += main.cpp\
mainwindow.cpp \
dialog1.cpp
HEADERS += mainwindow.h \
dialog1.h
FORMS += mainwindow.ui

RESOURCES += \
test1.qrc


Thanks to anyone who can help in this mater.

Sergio

and, finally, the mainwindow.cpp:

I attached it to this post because this forum allows only code with less than 10,000 chars.

ChrisW67
25th April 2011, 22:56
QSignalMapper is designed for this sort of thing.

squidge
25th April 2011, 23:12
The problem i sthat I have to create one QDialog for each of the tanks because the slot() don't accept a value in it's call.No, but in the slot you can use sender() to find out the object that sent the signal, or use QSignalMapper to map the object reference to a id (such as an integer). You can then use this id to reference into an array, for example.

ssaguiar
25th April 2011, 23:21
Ok, thanks.
I will study it and try to implement.

Sergio

ssaguiar
26th April 2011, 02:38
Ok, Let's see what I have done...

In mainwindow.h, I added this:



#include <QSignalMapper>
.
.
.
and
.
.
private slots:
.
id View_tank_Details(QString local);



In my mainwindow.ccp I have implemented this code:




.
.
QSignalMapper *signalMapper;
signalMapper = new QSignalMapper(this);
.
.



View_tank1 = new QPushButton( "Tank1", this );
View_tank1->setFlat(true);
View_tank1->setIcon (ButtonIcon);
//View_tank1->setFixedSize(16,16);
View_tank1->setGeometry( QRect( 160, 10, 16, 16 ));
View_tank1->setCursor(Qt::ArrowCursor);
connect(View_tank1, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank1, View_tank1->text());


View_tank2 = new QPushButton( "Tank2", this );
View_tank2->setFlat(true);
View_tank2->setIcon (ButtonIcon);
//View_tank2->setFixedSize(16,16);
View_tank2->setGeometry( QRect( 350, 10, 16, 16 ));
View_tank2->setCursor(Qt::ArrowCursor);
connect(View_tank2, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank2, View_tank2->text());

View_tank3 = new QPushButton( "Tank3", this );
View_tank3->setFlat(true);
View_tank3->setIcon (ButtonIcon);
//View_tank3->setFixedSize(16,16);
View_tank3->setGeometry( QRect( 550, 10, 16, 16 ));
View_tank3->setCursor(Qt::ArrowCursor);
connect(View_tank3, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank3, View_tank3->text());

View_tank4 = new QPushButton( "Tank4", this );
View_tank4->setFlat(true);
View_tank4->setIcon (ButtonIcon);
//View_tank4->setFixedSize(16,16);
View_tank4->setGeometry( QRect( 760, 10, 16, 16 ));
View_tank4->setCursor(Qt::ArrowCursor);
connect(View_tank4, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank4, View_tank4->text());

View_tank5 = new QPushButton( "Tank5", this );
View_tank5->setFlat(true);
View_tank5->setIcon (ButtonIcon);
//View_tank5->setFixedSize(16,16);
View_tank5->setGeometry( QRect( 160, 110, 16, 16 ));
View_tank5->setCursor(Qt::ArrowCursor);
connect(View_tank5, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank5, View_tank5->text());

View_tank6 = new QPushButton( "Tank6", this );
View_tank6->setFlat(true);
View_tank6->setIcon (ButtonIcon);
//View_tank6->setFixedSize(16,16);
View_tank6->setGeometry( QRect( 350, 110, 16, 16 ));
View_tank6->setCursor(Qt::ArrowCursor);
connect(View_tank6, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank6, View_tank6->text());

View_tank7 = new QPushButton( "Tank7", this );
View_tank7->setFlat(true);
View_tank7->setIcon (ButtonIcon);
//View_tank7->setFixedSize(16,16);
View_tank7->setGeometry( QRect( 550, 110, 16, 16 ));
View_tank7->setCursor(Qt::ArrowCursor);
connect(View_tank7, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank7, View_tank7->text());

View_tank8 = new QPushButton( "Tank8", this );
View_tank8->setFlat(true);
View_tank8->setIcon (ButtonIcon);
//View_tank8->setFixedSize(16,16);
View_tank8->setGeometry( QRect( 760, 110, 16, 16 ));
View_tank8->setCursor(Qt::ArrowCursor);
connect(View_tank8, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank8, View_tank8->text());

View_tank9 = new QPushButton( "Tank9", this );
View_tank9->setFlat(true);
View_tank9->setIcon (ButtonIcon);
//View_tank9->setFixedSize(16,16);
View_tank9->setGeometry( QRect( 160, 210, 16, 16 ));
View_tank9->setCursor(Qt::ArrowCursor);
connect(View_tank9, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank9, View_tank9->text());

View_tank10 = new QPushButton( "Tank10", this );
View_tank10->setFlat(true);
View_tank10->setIcon (ButtonIcon);
//View_tank10->setFixedSize(16,16);
View_tank10->setGeometry( QRect( 350, 210, 16, 16 ));
View_tank10->setCursor(Qt::ArrowCursor);
connect(View_tank10, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank10, View_tank10->text());

View_tank11 = new QPushButton( "Tank11", this );
View_tank11->setFlat(true);
View_tank11->setIcon (ButtonIcon);
//View_tank11->setFixedSize(16,16);
View_tank11->setGeometry( QRect( 550, 210, 16, 16 ));
View_tank11->setCursor(Qt::ArrowCursor);
connect(View_tank11, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank11, View_tank11->text());

View_tank12 = new QPushButton( "Tank12", this );
View_tank12->setFlat(true);
View_tank12->setIcon (ButtonIcon);
//View_tank12->setFixedSize(16,16);
View_tank12->setGeometry( QRect( 760, 210, 16, 16 ));
View_tank12->setCursor(Qt::ArrowCursor);
connect(View_tank12, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank12, View_tank12->text());

View_tank13 = new QPushButton( "Tank13", this );
View_tank13->setFlat(true);
View_tank13->setIcon (ButtonIcon);
//View_tank13->setFixedSize(16,16);
View_tank13->setGeometry( QRect( 160, 310, 16, 16 ));
View_tank13->setCursor(Qt::ArrowCursor);
connect(View_tank13, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank13, View_tank13->text());

View_tank14 = new QPushButton( "Tank14", this );
View_tank14->setFlat(true);
View_tank14->setIcon (ButtonIcon);
//View_tank14->setFixedSize(16,16);
View_tank14->setGeometry( QRect( 350, 310, 16, 16 ));
View_tank14->setCursor(Qt::ArrowCursor);
connect(View_tank14, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank14, View_tank14->text());

View_tank15 = new QPushButton( "Tank15", this );
View_tank15->setFlat(true);
View_tank15->setIcon (ButtonIcon);
View_tank15->setGeometry( QRect( 550, 310, 16, 16 ));
View_tank15->setCursor(Qt::ArrowCursor);
connect(View_tank15, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank15, View_tank15->text());

View_tank16 = new QPushButton( "Tank16", this );
View_tank16->setFlat(true);
View_tank16->setIcon (ButtonIcon);
View_tank16->setGeometry( QRect( 760, 310, 16, 16 ));
View_tank16->setCursor(Qt::ArrowCursor);
connect(View_tank16, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank16, View_tank16->text());

connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(View_tank_Details(QString)));


And, to test, I have implemented the View_tank_details as:



void MainWindow::View_tank_Details(QString local)
{

QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Warning);
msgBox.setText(local);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();


Now, I will implement a routine to generate the QPushButton in a loop and attach the index of them to the slot, because, as I have done, using the button text, I have lost the button's image (the image can't be seen, just the text).

Now, I wish to know how can I call the dialog class, wich is implemented in dialog1.ccp file this way:



#include "mainwindow.h"
#include <dialog1.h>

Dialog::Dialog( QWidget* Parent, Qt::WFlags Flags ) : QDialog( Parent, Flags )
{
setWindowTitle( tr( "Tanque 1" ) );
resize( QSize(800, 480).expandedTo(minimumSizeHint()) );
setWindowFlags(this->windowFlags() & Qt::Window | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
this->setStyleSheet( "background-image: url(:/images/background_main.png)");

QPushButton *Button = new QPushButton( tr( "ok" ), this );
QLCDNumber *Tanque1Level = new QLCDNumber(5, this);

Tanque1Level->setGeometry( 10, 10, 180, 80 );
Tanque1Level->setSmallDecimalPoint( false );
Tanque1Level->setNumDigits( 5 );
Tanque1Level->setSegmentStyle(QLCDNumber::Flat);
Tanque1Level->setFrameShape(QLCDNumber::Box);
Tanque1Level->setFrameShadow(QLCDNumber::Sunken);
Tanque1Level->setMode(QLCDNumber::Dec);
Tanque1Level->setStyleSheet("background: transparent;color:rgb(0,255,0); border: 2px solid grey;");
Tanque1Level->display(12976);

Button->setGeometry( QRect( 750, 440, 40, 30 ) );
connect( Button, SIGNAL( clicked() ), this, SLOT( close() ) );

}


Thanks to all for your help.

Just one more observation:

If I could intercept (if it existed) the event onclick over the lcd numbers, I could not use the buttons to call the View_tank_Details.
Is there any idea about this aproach?

Thanks again.

ChrisW67
26th April 2011, 07:37
Sounds like you want to override the default (do-nothing) QWidget::mousePressEvent()


#include <QtGui>
#include <QDebug>

class MyLCDNumber: public QLCDNumber {
Q_OBJECT
public:
MyLCDNumber(QWidget *p = 0): QLCDNumber(p) {
}
protected:
void mousePressEvent(QMouseEvent *event) {
qDebug() << "mousePressEvent received";
int val = intValue();
display(++val);
event->accept();
}
};

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

MyLCDNumber n;
n.setGeometry(100, 100, 100, 50);
n.display(23);
n.show();
return app.exec();
}
#include "main.moc"

ssaguiar
26th April 2011, 16:02
Ok, I got how to make my dialog work, receiving the text from the main window (as I posted before, thanks to all my friends who helped).

To create the dialog, I use this code:


void MainWindow::View_tank_Details(QString local)
{

QDialog *Tank_Details = new QDialog();
QPushButton *Button = new QPushButton( tr( "ok" ), Tank_Details);
QLCDNumber *Tanque1Level = new QLCDNumber(5, Tank_Details );

Tank_Details->setWindowFlags(Tank_Details->windowFlags() & Qt::Window | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
Tank_Details->setGeometry(x,y,800,480);
Tank_Details->show();
Tank_Details->activateWindow();
Tank_Details->setStyleSheet( "background-image: url(:/images/background_main.png)");

Tanque1Level->setGeometry( 10, 10, 180, 80 );
Tanque1Level->setSmallDecimalPoint( false );
Tanque1Level->setNumDigits( 5 );
Tanque1Level->setSegmentStyle(QLCDNumber::Flat);
Tanque1Level->setFrameShape(QLCDNumber::Box);
Tanque1Level->setFrameShadow(QLCDNumber::Sunken);
Tanque1Level->setMode(QLCDNumber::Dec);
Tanque1Level->setStyleSheet("background: transparent;color:rgb(0,255,0); border: 2px solid grey;");
Tanque1Level->display(12976);

Button->setGeometry( QRect( 750, 440, 40, 30 ) );
connect( Button, SIGNAL( clicked() ), Tank_Details, SLOT( close() ) );
}


Now, it seems to work well.
I just have to make it work even when user clicks over the lcd numbers or when he clicks over the buttons (without loosing the image of the button, as it's now).

Cheers

ssaguiar
27th April 2011, 21:49
Ok, got it to work.

mainwindow.cpp:



.
.
QSignalMapper *signalMapper= new QSignalMapper(this);
.
.

View_tank1 = new QPushButton( "", this );
View_tank1->setFlat(true);
View_tank1->setIcon (ButtonIcon);
View_tank1->setGeometry( QRect( 160, 10, 16, 16 ));
View_tank1->setCursor(Qt::ArrowCursor);
View_tank1->setObjectName("Tanque_1");
View_tank1->setCursor(Qt::OpenHandCursor);
View_tank1->setStatusTip(tr("Detalhes do tanque."));
connect(View_tank1, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank1, View_tank1->objectName());// ->text());

View_tank2 = new QPushButton( "", this );
View_tank2->setFlat(true);
View_tank2->setIcon (ButtonIcon);
View_tank2->setGeometry( QRect( 350, 10, 16, 16 ));
View_tank2->setCursor(Qt::ArrowCursor);
View_tank2->setObjectName("Tanque_2");
View_tank2->setCursor(Qt::OpenHandCursor);
connect(View_tank2, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank2, View_tank2->objectName());
.
.
.
.
View_tank15 = new QPushButton( "", this );
View_tank15->setFlat(true);
View_tank15->setIcon (ButtonIcon);
View_tank15->setGeometry( QRect( 550, 340, 16, 16 ));
View_tank15->setCursor(Qt::ArrowCursor);
View_tank15->setObjectName("Tanque_15");
View_tank15->setCursor(Qt::OpenHandCursor);
connect(View_tank15, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank15, View_tank15->objectName());

View_tank16 = new QPushButton( "", this );
View_tank16->setFlat(true);
View_tank16->setIcon (ButtonIcon);
View_tank16->setGeometry( QRect( 760, 340, 16, 16 ));
View_tank16->setCursor(Qt::ArrowCursor);
View_tank16->setObjectName("Tanque_16");
View_tank16->setCursor(Qt::OpenHandCursor);
connect(View_tank16, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(View_tank16, View_tank16->objectName());

connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(View_tank_Details(QString)));
.
.
.
void MainWindow::View_tank_Details(QString local)
{

QIcon ico;
ico.addPixmap(QPixmap(":/images/exit-2.svg"), QIcon::Normal, QIcon::On);
ico.addPixmap(QPixmap(":/images/exit.svg"), QIcon::Normal, QIcon::Off);

QDialog *Tank_Details = new QDialog();
QLabel *GraphPlot = new QLabel(Tank_Details);
QLabel *GraphTitle = new QLabel(Tank_Details);
QPushButton *ExitButton = new QPushButton("", GraphTitle);
QLCDNumber *Tanque1Level = new QLCDNumber(5, GraphTitle );

Tank_Details->setWindowFlags(Tank_Details->windowFlags() & Qt::Window | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
Tank_Details->setGeometry(x,y,800,480);
Tank_Details->show();
Tank_Details->activateWindow();
Tank_Details->setStyleSheet( "background-image: url(:/images/background_main.png)");

Tanque1Level->setGeometry( 10, 5, 180, 50 );
Tanque1Level->setSmallDecimalPoint( false );
Tanque1Level->setNumDigits( 5 );
Tanque1Level->setSegmentStyle(QLCDNumber::Flat);
Tanque1Level->setFrameShape(QLCDNumber::NoFrame);
Tanque1Level->setFrameShadow(QLCDNumber::Plain);
Tanque1Level->setMode(QLCDNumber::Dec);
Tanque1Level->setStyleSheet("background: transparent;color:rgb(0,255,0); border: 0px;");
Tanque1Level->display(12976);

GraphTitle->setGeometry(10, 20, 780, 60);
//set font
QFont font;
font.setPointSize(32);
font.setBold(true);
GraphTitle->setFont(font);
GraphTitle->setAutoFillBackground(true);
GraphTitle->setAlignment( Qt::AlignCenter );
GraphTitle->setFrameStyle( QFrame::Panel | QFrame::Raised );
GraphTitle->setStyleSheet("color:rgb(255,255,255);border: 1px solid grey;");
GraphTitle->setText(local);

GraphPlot->setGeometry(10, 90, 780, 380);
GraphPlot->setStyleSheet("border: 1px solid grey;");

ExitButton->setIcon(QIcon(ico));
ExitButton->setText(tr(""));
ExitButton->setFlat(true);
ExitButton->setIconSize(QSize(32,32));
ExitButton->setGeometry( QRect( 740, 14, 32, 32));
ExitButton->setCursor(Qt::OpenHandCursor);
ExitButton->setStyleSheet("background: transparent;border: 0px;");

connect( ExitButton, SIGNAL( clicked() ), Tank_Details, SLOT( close() ) );

}


Now, I want to plot 2D data in the QLabel GraphPlot, but, as it's created dinamically, I don't know where I can put the paintEvent.

I will start a new thread asking the question about the 2D plot.

Thanks to all who helped me.