I have a problem. I want to load and show data entries (xml) in a folder into a table. The form looks like this:
I have got a number of xml files in a folder:
QString path = QCoreApplication::applicationDirPath()+"/data/";
a sample xml (entry_1) looks like this:
<!DOCTYPE dataentry>
<subject_details>
<Name>Pete</Name>
<Surname>Batty</Surname>
<Patient_ID>GH34TRM</Patient_ID>
<Date>06/11/2019 16:00</Date>
</subject_details>
If I have a number of entries, entry 2, entry 3, entry 4 etc.
How do I parse contents from each entry and display in a Table?
Thanks in advance
Create a QDirIterator to iterate through all
the files in a directory. You can add a filter so it only will look
for files in the format of entry_number.xml.
Use a QXmlStreamReader to iterate thorough all the elements of
the XML file. Since you know the format of the XML file, you can
just look for your specific elements.
Add a new entry to your table. in this instance I used a
QTableWidget since it was not clear if you were using that or a
QTableView (next time please include some of the code you already have).
Format your table as necessary.
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QFile>
#include <QDirIterator>
#include <QXmlStreamReader>
#include <QMessageBox>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
void parseDataEntry(const QString dataPath);
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Setup table
ui->tableWidget->setColumnCount(4);
ui->tableWidget->setHorizontalHeaderLabels(QStringList{"Patient ID","Name", "Surname", "LastSession"});
ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
// Our data path
QString path = QCoreApplication::applicationDirPath()+"/data/";
// Filter only files that fit our naming convention.
QStringList qdiFilter("entry_*.xml");
// Iterate through all found files, parse each file to be added to the table.
QDirIterator qdi( path, qdiFilter, QDir::Files);
while (qdi.hasNext())
{
parseDataEntry(qdi.next());
}
}
void MainWindow::parseDataEntry(const QString dataPath)
{
QString patientID, firstName, surName, lastSession = "";
// Load our XML file.
QFile *xmlFile;
xmlFile = new QFile(dataPath);
if(!xmlFile->open(QIODevice::ReadOnly | QIODevice::Text))
{
QMessageBox::critical(this,
"Error Loading Patient Data File",
QString("Could not load the patient XML data file at:\r\n %0").arg(dataPath),
QMessageBox::Ok);
return;
}
// Create an XML reader.
QXmlStreamReader *xmlReader;
xmlReader = new QXmlStreamReader(xmlFile);
// Parse each element of the XML until we reach the end.
while(!xmlReader->atEnd() && !xmlReader->hasError()) {
// Read next element
QXmlStreamReader::TokenType token = xmlReader->readNext();
// If token is just StartDocument - go to next
if(token == QXmlStreamReader::StartDocument) {
continue;
}
// If token is StartElement - read it
if(token == QXmlStreamReader::StartElement) {
if(xmlReader->name() == "Name") {
firstName = xmlReader->readElementText();
} else if(xmlReader->name() == "Surname") {
surName = xmlReader->readElementText();
}
else if(xmlReader->name() == "Patient_ID") {
patientID = xmlReader->readElementText();
}
else if(xmlReader->name() == "Date") {
lastSession = xmlReader->readElementText();
}
}
}
if(xmlReader->hasError()) {
QMessageBox::critical(this,
"Error Parsing Patient Data File",
QString("Error reading the patient file at:\r\n %0,\r\nError: %1").arg(dataPath,
xmlReader->errorString()),
QMessageBox::Ok);
return;
}
// close reader and flush file
xmlReader->clear();
xmlFile->close();
// Delete
delete xmlFile;
delete xmlReader;
// Add a new row to the table, with the data we parsed.
ui->tableWidget->insertRow(ui->tableWidget->rowCount());
ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1,
0,
new QTableWidgetItem(patientID));
ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1,
1,
new QTableWidgetItem(firstName));
ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1,
2,
new QTableWidgetItem(surName));
ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1,
3,
new QTableWidgetItem(lastSession));
}
MainWindow::~MainWindow()
{
delete ui;
}
Related
I'm creating a very simple disk space analyzer that shows ocupied size of every file in specific foder and its subfolders. I'm using QStack to store paths and QTableWidget for showing next information (File Name, File Path, File Size and Last Modified Date). First of all I use QDirIterator to fill QStack, then in different thread I get necessary information about file by QFileInfo and add row in QTableWidget with this information. Populating QStack is quick but filling QTableWidget is very slow. The question is how can I boost speed of filling QTableWidget.
dialog.h
#include <QDialog>
#include <QStack>
#include "mythread.h"
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
MyThread *mThread;
QStack<QString> *fileStack;
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
public slots:
void onFileAdded(QString file);
private:
Ui::Dialog *ui;
};
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include "mythread.h"
#include <QFileDialog>
#include <QDirIterator>
#include <QMessageBox>
#include <QFileInfo>
#include <QDateTime>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
ui->tableWidget->setColumnCount(4);
ui->tableWidget->setHorizontalHeaderLabels(QStringList() << "File name" << "File Path" << "File Size (KB)" << "Last Modified Date");
fileStack = new QStack<QString>();
ui->tableWidget->setSortingEnabled(true);
mThread = new MyThread(this);
connect(mThread, SIGNAL(fileAdded(QString)), this, SLOT(onFileAdded(QString)));
}
Dialog::~Dialog()
{
delete ui;
delete mThread;
delete fileStack;
}
void Dialog::onFileAdded(QString file) {
QFileInfo fileInfo;
fileInfo.setFile(file);
ui->tableWidget->insertRow(ui->tableWidget->rowCount());
ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1,
0,
new QTableWidgetItem(fileInfo.fileName()));
ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1,
1,
new QTableWidgetItem(fileInfo.filePath()));
int sss = fileInfo.size() / 1024;
QTableWidgetItem *item = new QTableWidgetItem;
item->setData(Qt::EditRole, sss);
ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1,
2,
item);
ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1,
3,
new QTableWidgetItem(fileInfo.lastModified().toString()));
//ui->tableWidget->resizeColumnsToContents();
//ui->tableWidget->resizeRowsToContents();
}
void Dialog::on_pushButton_clicked()
{
QString dirname = QFileDialog::getExistingDirectory(this, tr("Select a Directory"), QDir::currentPath());
ui->lineEdit->setText(dirname);
}
void Dialog::on_pushButton_2_clicked()
{
QDirIterator it(ui->lineEdit->text(), QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext()) {
fileStack->push(it.next());
}
QMessageBox msgBox;
msgBox.setText("Completed");
msgBox.exec();
mThread->dir = fileStack;
mThread->start();
}
I create a player for audiobooks - when you open a folder with mp3 file, whole list of them is added to playlist and List View. And i have a Label, which suppose to show duration of the whole book. But player->duration returns only a duration of current track, and if i go through the loop and do playlist->next() every step, player->duration returns 0. I know about Phonon and file metadata, but i need to do this without using it.
I am attaching a source code of a working project, you can use. When the player changes the file, the duration is changed and printed out. To loop within files, there is a need to wait till the decoder completes reading the media file. See the code below and the comments.
This is mainwindow.cpp
#include "mainwindow.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
bool done =false;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
player = new QMediaPlayer(this);
playlist = new QMediaPlaylist(player);
playlist->setPlaybackMode(QMediaPlaylist::Sequential);
player->setPlaylist(playlist);
connect(player, &QMediaPlayer::durationChanged, this, &MainWindow::on_durationchanged);
//connect(player,&QMediaPlayer::)
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
playlist->addMedia(QUrl::fromLocalFile("Ar_today.mp3"));
playlist->addMedia(QUrl::fromLocalFile("Ar_sunday.mp3"));
playlist->setCurrentIndex(0); //set the first file
while (done == false) //wait till the duration is read
{
QApplication::processEvents();
}
done = false; playlist->setCurrentIndex(1); //change to the second file
while (done == false) //wait till the duration is read
{
QApplication::processEvents();
} //this way you can loop through files
player->setVolume(80);
player->play();
qDebug() << player->errorString();
}
void MainWindow::on_pushButton_2_clicked()
{
player->stop();
}
void MainWindow::on_durationchanged(qint64 duration)
{
done = true;
qDebug() << "duration = " << player->duration();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QDebug>
extern bool done;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_durationchanged(qint64 duration);
private:
Ui::MainWindow *ui;
QMediaPlayer* player;
QMediaPlaylist* playlist;
};
#endif // MAINWINDOW_H
In the form, create 2 buttons, one called pushbutton to play and the other is pushButton_2 to stop
I want to display a "generating image..." kind of modal dialog, other than the main GUI. This "generating image..." dialog should be temporary, and be displayed and disappear without user intervention.
For displaying this dialog, the Qt code should check for existence of a .txt file in a specific location in the PC's hard disk. If the .txt file exists, then the dialog should pop-up.
For making this dialog disappear, the Qt code should check whether that .txt file contains the string "OK" in the first line. The dialog should disappear only when this "OK" is found, until then it should continue to display "generating image..."
A good way to do this is to use signal slot mechanism. I would like to know, what functions should be used as SIGNALS in both the cases, of displaying and removing the dialog.
So far, I could manage a simple code, illustrating a "generating image..." using signal slot mechanism, but with setValue() and pressing a push button(i.e. involving user intervention), and not with the checking of .txt file or the "OK" string inside that .txt file(user non-intervention).
Please advise me, whether my logic can be implemented? If yes, how? Also, what SIGNALs should be used?
************************UPDATED SECTION(as of Feb 24th '14):****************************************************
I have revised the code according to Dmitry Sazonov's suggestions. I am able to display the loading GIF whenever a new file is created/deleted in a designated directory. Now I want to close this loading qDialog, when the usbResponse.txt file has "ok" inside it. I tried using signal slot, to implement hide(), but could not get it.
I do not get errors, but the qDialog window does not close as expected. I tried both, secDialog.close() and secDialog.hide(), but the window didn't close. Perhaps because the secDialog object is not the same in both the SLOTs. So I also made secDialog, a global object, but I received an error as follows:-
QWidget: Must construct a QApplication before a QWidget
I looked it up: https://qt-project.org/forums/viewthread/12838
Changed the build modes, accordingly, but that didn't help either. Please tell me how do I close my qDialogs, when I find the "ok" in usbResponse.txt file.
************************UPDATED SECTION(as of Mar 14th '14):****************************************************
I could close the qDialog containing the GIF using hide(). I have done a total overhaul of the code. As mentioned above, the qDialog containing the GIF should appear whenever a text file called usbResponse.txt exists at a designated location. Also taking #Dmitry Sazonov's advice, I am able to close the GIF whenever that txt file i.e. usbResponse.txt is modified, using FileSystemWatcher.
I'm continuously scanning for the existence of the .txt using threads. When I find the file, I display the loading GIF. When the .txt is modified the GIF should disappear. This works fine for the first iteration, i.e. when
(the following are observations after debugging)
the usbResponse.txt exists => GIF is displayed
when usbResponse.txt is modified => GIF is hidden & the .txt is deleted.
THe problem, in next iteraiton,(i.e. all iterations after the first)
the usbResponse.txt is created => the GIF is displayed.
when usbResponse.txt is modified, the debug pointer continues to remain in
afterFileHasBeenFound()
whereas it should have gone in
closeModified(const QString &str)
What is my mistake here?
Here is my code:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFile>
#include <QDebug>
#include <QFileSystemWatcher>
#include "dialog.h"
#include "mythread.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void afterFileHasBeenFound();
void closeModified(const QString &str);
private slots:
private:
Ui::MainWindow *ui;
Dialog *pDialog;
MyThread *mThread;
};
#endif // MAINWINDOW_H
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QMovie>
#include <QLabel>
#define GIF_PATH "E:\\QT1\\timeStampPopUp\\timeStampPopUp\\loading.gif"
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
void displayLoadingGif();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QtCore>
#include <QDebug>
#define FILE_PATH "E:\\QT1\\dialogClose2\\dialogClose2\\usbResponse.txt"
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = 0);
void run();
QString name;
int exec();
void checkFile();
signals:
void testSignal(QString message);
void fileFoundDisplayGif();
public slots:
};
#endif // MYTHREAD_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
displayLoadingGif();
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::displayLoadingGif()
{
QMovie *pMovie = new QMovie(GIF_PATH);
ui->loadingGifLabel->setMovie(pMovie);
pMovie->start();
}
mythread.cpp
#include "mythread.h"
MyThread::MyThread(QObject *parent) :
QThread(parent)
{
}
void MyThread::run()
{
exec();
}
int MyThread::exec()
{
while(1)
{
checkFile();
emit(testSignal("hello world!!"));
sleep(1);
}
}
void MyThread::checkFile()
{
QFile file(FILE_PATH);
if(file.exists())
{
qDebug()<<"exists";
emit(fileFoundDisplayGif());
}
else
qDebug()<<"doesn't exist";
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
mThread = new MyThread(this);
mThread->name = "mThread";
connect(mThread, SIGNAL(fileFoundDisplayGif()), this, SLOT(afterFileHasBeenFound()), Qt::QueuedConnection);
mThread->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::afterFileHasBeenFound()
{
if(pDialog != NULL)
return;
pDialog = new Dialog();
pDialog->setModal(true);
pDialog->show();
}
void MainWindow::closeModified(const QString &str)
{
Q_UNUSED(str)
if(pDialog != NULL)
{
pDialog->hide();
}
QFile file(FILE_PATH);
file.remove();
pDialog = NULL;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QFileSystemWatcher fileWatcher;
fileWatcher.addPath(FILE_PATH);
QStringList fileList = fileWatcher.files();
Q_FOREACH(QString file, fileList)
qDebug() << "File name " << file;
MainWindow* mc = new MainWindow;
QObject::connect(&fileWatcher, SIGNAL(fileChanged(QString)), mc, SLOT(closeModified(QString)));
mc->show();
return a.exec();
}
Do not use timers for checking file. Use QFileSystemWatcher for traking file modifications.
Implement a slot that will check file content on modification. And call hide() method, when your "OK" text appeared.
IMHO: your solution is to messy. There are a lot of other syncronization mechanisms between processed. Can you modify code of tool that generates image? Should it really work as another process?
I have three comboboxes with three similar options, 'one', 'two', 'three', and I want to prevent the same option in different combobox.
Example:
combobox1 : 'one',
so when I go choose in combobox2 and combobox3 there's only 'two' and 'three' to choose from.
I know I could do this in a combination of for loop and if, but can anyone help me with some trick I could use here?
Write your own class MyComboBox which is derived from QComboBox.
Implement a slot in MyComboBox that would do something like this:
void excludeIndex(const QString & text)
{
// Get the list of all the options for the ComboBox
QStringList list = getIndices();
// Remove one (the only) item 'text' from the list
list.removeOne( text );
// Clear the ComboBox and fill with the new values
this->clear();
this->addItems( list );
}
In your parent widget/application, connect the signal void currentIndexChanged(const QString & text) from each 'sending' MyComboBox or QComboBox to this slot of the 'receiving' MyComboBox.
If you need to exclude the values from multiple other ComboBoxes, then it might be better to implement the slot in the parent Widget. That way, you can loop over all the 'receiving' ComboBoxes. Per ComboBox you will read all the current values of the other ComboBoxes and remove those values from list. Your slot in the parent Widget will not need an input QString anymore.
How about using only one combobox? There are only six possible options:
one two three
one three two
two one three
two three one
three one two
three two one
It would be much easier for the user to use only one combobox instead of using three comboboxes whose available options are continuously changing.
Here is one solution.
Basically it initializes all of the boxes with all the items, and as a box's current text is changed, it removes that text from the other boxes. If the previous text that the box contained wasn't blank, it adds it back into all the other boxes.
If you care to test it with more than 8, change the variable m_numOfBoxes in mainwindow.cpp to some other value.
main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QComboBox>
#include <QList>
#include <QStringList>
#include <QMap>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void on_comboBox_changed();
private:
QList <QComboBox *> m_boxes;
QMap <QComboBox *, QString> m_previousText;
int m_numOfBoxes;
QStringList m_allItems;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QVBoxLayout>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QVBoxLayout * vbox = new QVBoxLayout();
m_numOfBoxes = 8;
m_allItems << "";
for(int i = 0; i< m_numOfBoxes; i++)
{
m_allItems << QString::number(i+1);
}
for(int i = 0; i< m_numOfBoxes; i++)
{
QComboBox * temp = new QComboBox;
QObject::connect(temp, SIGNAL(currentIndexChanged(int)), this, SLOT(on_comboBox_changed()));
vbox->addWidget(temp);
temp->addItems(m_allItems);
m_boxes.append(temp);
m_previousText[temp] = "";
}
this->setCentralWidget(new QWidget());
this->centralWidget()->setLayout(vbox);
}
MainWindow::~MainWindow()
{
}
void MainWindow::on_comboBox_changed()
{
QComboBox * editedBox = qobject_cast <QComboBox *> (QObject::sender());
QString currentText = editedBox->currentText();
if(currentText == m_previousText[editedBox])
{
return;
}
foreach(QComboBox * box, m_boxes)
{
if(box == editedBox)
{
continue;
}
if(currentText != "")
{
// remove the current text from the other boxes
int index = box->findText(currentText);
if(index != -1)
{
box->removeItem(index);
}
}
if(m_previousText[editedBox] != "")
{
// add the previous text back into the lists for the other boxes
box->addItem(m_previousText[editedBox]);
qDebug() << "Adding back" << m_previousText[editedBox];
}
}
m_previousText[editedBox] = currentText;
}
Note that when an item is added back into a box's list, it just gets tacked onto the end of the list, so over time the order of your items may get scrambled.
Hope that helps.
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;
}
}