QErrorMessage and QValidator - qt

I'm a student programmer and I'm trying to use some of the widgets provided in Qt to control my user input. I want the error message to display exactly whats wrong with the user input so I thought that using a switch statement would be best. I may not be correct about this and if there is a better way of doing this I am all ears! My main project will get allot of user input and it feels like there should be an easier way. The Qt Documentation lead me to believe that QValidator is at heart an enumerator data type. So I though I could use it in the switch statement however it doesn't seem to come up as an int. I'm not sure how to bring in an int value to make this work without defeating the intended convenience of the QValidator.
Any info on how to make this work or do it better would be greatly appreciated. Thanks in advance.
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QValidator>
#include <QErrorMessage>
#include <QString>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->pushButtonValidate, SIGNAL(clicked()), this, SLOT(checkData()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::checkData()
{
QValidator *doubleValidator = new QDoubleValidator();
switch(ui->lineEditValidate->setValidator(doubleValidator))
{
case 0:
QErrorMessage *error0 = new QErrorMessage(this);
error0->showMessage("The input is invalid");
break;
case 1:
QErrorMessage *error1 = new QErrorMessage(this);
error1->showMessage("The input is incomplete");
break;
case 2:
break;
default:
QErrorMessage *error = new QErrorMessage(this);
error->showMessage("No input");
}
}

In this line of code
switch(ui->lineEditValidate->setValidator(doubleValidator))
you're attempting to switch on the return value of the setValidator() function call, which returns void.
From what I gather, it looks like you want to do something along these lines:
In the constructor:
ui->setupUi(this);
connect(ui->pushButtonValidate, SIGNAL(clicked()), this, SLOT(checkData()));
QValidator *doubleValidator = new QDoubleValidator();
ui->lineEditValidate->setValidator(doubleValidator);
and in checkData()
int pos = 0;
switch(ui->lineEditValidate->validator()->validate(ui->lineEditValidate->text(), pos))
{
case QValidator::Invalid:
...
case QValidator::Incomplete:
...
case QValidator::Invalid:
...
}

Related

Qt call to update not triggering call to paintEvent() while drawing data from serial port to scrollArea

I am newbie to Qt 5.1.0. My problem with Qt is showed directly as follows. Data from serial port is received by readdata(), then call the draw() in mainwindow.cpp to deliver the data to newpaint() in paint.cpp. Two classes are created in this project:class mainwindow is mainly responsible for receiving data from serial port,class paint is for drawing the data (actually the data is coordinates of a mathematical function) on the scroll area widget which is on the mainwindow.
But in paint.cpp, paintevent is not invoked by update().UpdateEnabled() returns true depicting that the problem doesn't exist in the use of update().
Main part is pasted below.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
QPainterPath linepath;
linepath.moveTo(0,0);
ui->setupUi(this);
paintwiget=new paint(linepath,ui->scrollArea);
ui->scrollArea->setWidget(paintwiget);
paintwiget->show();
ui->closeserial->setEnabled(false);
ui->sendData->setEnabled(false);
serial=new QSerialPort(this);
connect(serial,SIGNAL(readyRead()),this,SLOT(readData()));
}
void paint::newpaint(qreal *aa1, int len1)
{
if (!aa.isEmpty())
aa.clear();
int i;
for (i=0;i<len1;i++)
aa.append(aa1[i]);
// qDebug()<<aa.size();
//qDebug()<<"aa[0:3]"<<aa[0]<<" "<<aa[1]<<" "<<aa[2]<<" "<<aa[3];
len=len1;
// this->setVisible(true);
qDebug()<<this->isVisible();//now returns true
this->update();
//qDebug()<<"okla";
}
void paint::paintEvent(QPaintEvent *)
{
qDebug()<<"ok~~";
QPointF currentpoi;
QPainter painter(this);
int ii=0;
qDebug()<<len;
for (ii=0;ii<len/2;ii++)
{
currentpoi=path.currentPosition();
qDebug()<<"currentpoi"<<currentpoi;
path.moveTo(currentpoi);
path.lineTo(aa[2*ii],aa[2*ii+1]);
// painter.setRenderHint(QPainter::Antialiasing);
painter.drawPath(path);
}
}
paint.h
#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QTabWidget>
//#include <mainwindow.h>
class paint : public QWidget
{
public:
explicit paint(QPainterPath &path,QWidget *parent=0);
void newpaint(qreal *,int);
QVector <qreal>aa;
int len;
QWidget *parent;
private:
QPointF point;
QPainterPath path;
protected:
void paintEvent(QPaintEvent *event);
};
Hard to say for sure that this is the only issues you are facing, but there are at least three issues:
Issue 1
The following code tells me that you have a member of MainWindow called paint * paintwiget:
void MainWindow::draw(qreal *aa,int len)
{
// ...
paintwiget->newpaint(dist,len);
}
Then, this code tells me that you are creating a new temporary variable of the same name:
MainWindow::MainWindow(QWidget *parent)
{
// ...
paint *paintwiget=new paint(linepath,ui->scrollArea->viewport());
}
The compiler should have probably given you a warning for this. Replace this line by:
paintwiget = new paint(linepath,ui->scrollArea->viewport());
(notice the lack of paint *), and tell me if this solves the problem.
Issue 2
You have to change this:
void paint::newpaint(qreal *aa, int len)
{
// ...
aa[i]=aa[i];
len=len;
}
by this:
void paint::newpaint(qreal *aa_new, int len_new)
{
// ...
aa[i]=aa_new[i];
len=len_new;
}
Otherwise, your aa[i]=aa[i] has no effect: it replaces the parameter of the method by itself, instead of replacing your member by the parameter of the method. Using a parameter with the same name than a member "hides" the member: you can't access it anymore, either at the left hand side or the right hand side of an assignment.
Issue 3
I'm not quite sure what you are doing with scrollArea->viewport() in the constructor of paint, but something tells me you are doing it wrong. The constructor of paint should NOT use it, but instead, you should do:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QPainterPath linepath;
paintwiget = new paint(linepath); // Do NOT pass viewport in parameter
ui->scrollArea->setWidget(paintwiget);
paintwiget->show();
// ...
}

Display not updating on the QTimer?

Trying to display text based on when the QTimer fires off...
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
m_label1 = new QLabel("My Label not working", this);
QTimer* timerDisplay = new QTimer(this);
connect(timerDisplay, SIGNAL(Started()), this, SLOT(updateDisplay(this)));
timerDisplay->start(10);
}
void updateDisplay(MainWindow* m_this)
{
QString out;
out = "hello";
m_this->m_label1->setText("asdf");
}
connect(timerDisplay, SIGNAL(Started()), this, SLOT(updateDisplay(this)));
This statement is failing. And you're ignoring the message that Qt is printing on your console.
The problem is, you can't pass variables in connect statements like that. And what for, by the way? You can use this in the updateDisplay method without the need of passing it in explicitely!

Transfer inputs from qdialog to mainwindow

In qdialog i put some input that i need in the mainwindow, how can i get them? my program is something like this, I have a qdialog that must open before mainwindow, I put there some input and click ok, and then the mainwinodw opens using those inputs.
here's the dialog.cpp code:
#include "dialog.h"
#include "ui_dialog.h"
#include "vtkBMPReader.h"
// Define the length of the volume
void Dialog::bmprange()
{
// Getting some proprieties for the lenght of the volume
QString XMAX=ui->lineEdit->text();
double xMax=XMAX.toDouble();
QString YMAX=ui->lineEdit_2->text();
double yMax=YMAX.toDouble();
QString ZMAX=ui->lineEdit_3->text();
double zMax=ZMAX.toDouble();
QString XMMAX=ui->lineEdit_4->text();
double xMMax=XMMAX.toDouble();
QString YMMAX=ui->lineEdit_5->text();
double yMMax=YMMAX.toDouble();
QString ZMMAX=ui->lineEdit_6->text();
double zMMax=ZMMAX.toDouble();
if (xMax==0 || yMax==0 || zMax==0 || xMMax==0 || yMMax==0 || zMMax==0)
{
ui->label_17->setText("Error: invalid measures");
}
else
{
// Using vtkBMPReader to read all the 128 bmp slices
vtkBMPReader *bmp= vtkBMPReader::New();
bmp->SetDataByteOrderToLittleEndian();
bmp->SetFilePrefix ("/home/matt/Desktop/ouBMP/exemplo");
bmp->SetFilePattern("%s%d.bmp");
bmp->SetFileNameSliceSpacing(1);
bmp->SetNumberOfScalarComponents(3);
bmp->SetDataOrigin(0,0,0);
bmp->SetDataSpacing(xMMax/(xMax-1.0),xMMax/(yMax-1.0),xMMax/(zMax-1.0));
bmp->SetDataExtent(0,xMax-1.0,0,yMax-1.0,1,zMax);
bmp->Update();
ui->label_17->setText("Valid measures");
}
}
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
// Control volume measures
// Making the lineedit objects only accept numbers
ui->lineEdit->setValidator(new QIntValidator(this));
ui->lineEdit_2->setValidator(new QIntValidator(this));
ui->lineEdit_3->setValidator(new QIntValidator(this));
ui->lineEdit_4->setValidator(new QDoubleValidator(this));
ui->lineEdit_5->setValidator(new QDoubleValidator(this));
ui->lineEdit_6->setValidator(new QDoubleValidator(this));
connect(ui->lineEdit, SIGNAL(textChanged(QString)), this, SLOT(bmprange()));
connect(ui->lineEdit_2, SIGNAL(textChanged(QString)), this, SLOT(bmprange()));
connect(ui->lineEdit_3, SIGNAL(textChanged(QString)), this, SLOT(bmprange()));
connect(ui->lineEdit_4, SIGNAL(textChanged(QString)), this, SLOT(bmprange()));
connect(ui->lineEdit_5, SIGNAL(textChanged(QString)), this, SLOT(bmprange()));
connect(ui->lineEdit_6, SIGNAL(textChanged(QString)), this, SLOT(bmprange()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::changeEvent(QEvent *e)
{
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
how can i get bmp, xMax, ... to use in mainwindow
I don't speak C++, so sorry for the lack of details. Here's what I'd do:
Catch the closeEvent that you should have when you close your dialog. If your dialog has a OK button, you can use its clicked signal.
Connect it to a particular slot whose functions are (1) to retrieve the texts of all your dialog's QLineEdit in a single object (a QStringList, for example) and (2) to actually close your dialog.
Store the content of this QStringList as an attribute of your main window, or as an independent object you can retrieve from your main window.

displaying instance of class in tabs in Qt

Im trying to display 3 forms(calender, history, statistics) which has 3 classes into a MainWindow Class which has three tabs created using the designer. When the application runs for the first time, it displays the history form into the tab. But when it is being run the second time, the form is displayed over the tabs that they are not visible.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
CalenderForm *pCal = new CalenderForm();
lay = new QVBoxLayout(ui->tab);
lay->addWidget(pCal);
connect(ui->tabWidget,SIGNAL(currentChanged(int)),this,SLOT(a(int)));
}
void MainWindow::a(int index)
{
switch(index)
{
case 0:
callCal();
break;
case 1:
callHist();
break;
default:
break;
}
}
void MainWindow::callHist()
{
HistoryForm *pHis = new HistoryForm();
pHis->DisplayHistory();
pHis->show();
lay2 = new QVBoxLayout(ui->tab_2);
lay2->addWidget(pHis);
}
Everytime you switch the tab index, you create a new form. I am not sure if this is the cause of your problem, but it definitely is a problem.
You should ensure the forms are only created once. For example you may create them in the constructor of MainWindow and store pointers to them in member variables. You should also already assign any required layouts there.
When you switch the index, you just call the DisplayHistory() or equivalent method.
PS: If you still want to understand your code next year, you should probably find a more speaking name than "a" for that slot ;-)
[Edit]
Here is a sample header and cpp file. Be adviced that it might not compile as is and you might have to do some adjustments, but I wanna show you the general idea.
Header file
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui/QMainWindow>
// forward declarations
class CalendarForm;
class HistoryForm;
class StatisticsForm; // or whatever your 3rd form is called
class MainWindow : QMainWindow
{
public:
MainWindow(QWidget *parent);
~MainWindow();
private slots:
void currentTabChanged( int tabIndex );
private:
// these are called "member variables" as they are a member of a class
// Sample naming convention: m_ for members, p for Pointer, you can use
// whatever you prefer, as long as you use it consistently.
CalendarForm* m_pCalendar;
HistoryForm* m_pHistory;
StatisticsForm* m_pStatistics;
// not sure about this part but it is generated by Qt anyway
Ui::MainWindowClass* ui;
};
// not sure about this part but it is generated by Qt anyway
namespace Ui {
class MainWindowClass;
}
#endif // MAINWINDOW_H
CPP File:
// these includes should be present already anyway
#include "MainWindow.h"
#include "ui_mainwindow.h"
#include "CalendarForm.h"
#include "HistoryForm.h"
#include "StatisticsForm.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
m_pCalendar = new CalendarForm();
m_pHistory = new HistoryForm();
m_pStatistics = new StatisticsForm();
ui->tabWidget->addTab( m_pCalendar );
ui->tabWidget->addTab( m_pHistory );
ui->tabWidget->addTab( m_pStatistics );
connect( ui->tabWidget, SIGNAL( currentChanged ( int ) ),
this , SLOT ( currentTabChanged( int ) );
}
MainWindow::~MainWindow()
{
delete m_pCalendar;
delete m_pHistory;
delete m_pStatistics;
}
void MainWindow::currentTabChanged( int tabIndex )
{
switch( tabIndex )
{
case 0:
// update calculator if necessary
break;
case 1:
// Assumption: You need to update the view every time you activate
// the tab. If this assumption is wrong, you don't need this slot
// at all, just call the method once in the constructor.
m_pHistory->DisplayHistory();
break;
case 2:
// update statistics if necessary
break;
default:
break;
}
}

Qt: Trying to do a httprequest, but does not seem to work. What is wrong?

I've been using this example to create a http request for my Qt Nokia application, but I can't seem to get it working.
At first I Tried QHttp, but it is deprecated.
Here's the structure:
mainwindow.cpp
mainwindow.h
request.cpp
request.h
Here's the code:
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
Request* request = new Request();
}
MainWindow::~MainWindow()
{
delete ui;
}
Request.h
#ifndef REQUEST_H
#define REQUEST_H
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkReply>
#include <QNetworkRequest>
class Request : QObject
{
//Q_OBJECT
public:
Request();
public slots:
void finishedSlot(QNetworkReply* reply);
void checkConnection(QNetworkReply* reply);
};
#endif // REQUEST_H
And btw... what use is the "Q_OBJECT" for?
Request.cpp
#include "request.h"
#include <QDebug>
#include <QMessageBox>
Request::Request()
{
QNetworkAccessManager* oNetworkAccessManager = new QNetworkAccessManager(this);
QObject::connect(oNetworkAccessManager, SIGNAL(finished(QNetworkReply*)),this,SLOT(finishedSlot(QNetworkReply*)));
QObject::connect(oNetworkAccessManager, SIGNAL(networkSessionConnected()),this,SLOT(checkConnection(QNetworkReply*)));
QUrl url("http://www.redrock.no");
QNetworkReply* reply = oNetworkAccessManager->get(QNetworkRequest(url));
}
void Request::checkConnection(QNetworkReply* reply)
{
QMessageBox msgBox;
msgBox.setText("checkConnection");
msgBox.setInformativeText("The network session has started");
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();
}
void Request::finishedSlot(QNetworkReply* reply)
{
QMessageBox msgBox;
msgBox.setText("checkConnection");
msgBox.setInformativeText("The request is done");
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();
}
The message boxes is just since I don't have a usb cable for my phone.
I have set breakpoints at both the "checkConnection" slot and the "finishedSlot" slot, but nothing happens there.
Anyone got an idea of what I could be doing wrong?
Here is an explanation of the Q_OBJECT macro:
http://doc.qt.nokia.com/latest/qobject.html#Q_OBJECT
Among other things,
The Q_OBJECT macro must appear in the
private section of a class definition
that declares its own signals and
slots...
So I would first try uncommenting that and see what changes. It should at least get your signals and slots talking to one another. (This is a Qt-specific feature, not part of C++, and needs the Q_OBJECT macro.) I didn't look carefully at the rest of your code, because that is the obvious first thing to try. Actually, I am surprised that it would even compile without that.
ok, finally i found what's wrong... and as usual, it's just a minor error from me.
I uncommented the Q_OBJECT, and got some vtable error or something like that. I did get this error message earlier today when i had the Q_OBJECT there, and that is why i commenting it.
But since i'm new to Qt i hade forgot to incelude the QObject in the request.h
"#include "
And that fixed everything for me :)
Thanks for the explenation and elaboration Dave.

Resources