[SOLVED]Passing variables between QMainWindows
-
Hello,
I have a question. As i'm working on my small project i encountered a problem that i can't overcome. It's my first time with QT so my knowledge about this framework is not impressive. I tried to look for some answers on google, but nothing applied to me. Every topic is about passing stuff from QDialog to parent window which is fairly easy, but im in need to pass custom variable from one QMainWindow to another. Let me first paste the code
mainwindow.h
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QList>
#include "invoicemodulewindow.h"
#include "magazinemodule.h"
#include "contractormodule.h"
#include "individualclientmodule.h"#include "invoice.h"
namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget parent = 0);
~MainWindow();
QList<Invoice> invoices; //this variable has to know about invoices from invoiceModule};
#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);
}MainWindow::~MainWindow()
{
delete ui;
for(int i = 0; i < invoices.size(); i++){
delete invoices.at(i);
}
}
/*
this is where i call invoiceModuleWindow, here i need to somehow return invoices from this module to the
variable above
*/
void MainWindow::on_invoiceModule_clicked()
{
invoiceModuleWindow = new InvoiceModuleWindow(invoices, this);
invoiceModuleWindow->show();}@
My problem is that i need to pass variable invoicess from invoiceModule to invoices from main window before i call the destructor. Invoice module is called from main window. Later i want those invoices to interact with other modules (as contractor module etc), that's why i need the knowledge about invoices in main window. Maybe i am doing sth wrong here, but i can't find the solution. Secondly i need to use QMainWindow because of the toolbar and other stuff that i need. Is there any gentle way to do such thing, or im screwed?
Consider that i'm not fully skilled in C++ and QT and this app is in very early version, so please don't be harsh.
Thanks in advance for resposne.
PS. i tried with some SIGNAL, SLOT stuff but i failed.
-
Pasting another code, op post was to large
invoicemodulewindow.h
@#ifndef INVOICEMODULEWINDOW_H
#define INVOICEMODULEWINDOW_H#include <QMainWindow>
#include <QDialog>
#include <QStandardItemModel>
#include <QList>
#include <QFileDialog>
#include <QMessageBox>
#include "addinvoicedialog.h"
#include "invoice.h"namespace Ui {
class InvoiceModuleWindow;
}class InvoiceModuleWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit InvoiceModuleWindow(QList<Invoice*> invoices, QWidget parent = 0);
~InvoiceModuleWindow();
QList<Invoice> getInvoices(); //method that returns invoicesprivate:
Ui::InvoiceModuleWindow *ui;
QStandardItemModel model;
QList<Invoice> invoicess; //this variable stores current invoices in this module, i need to pass it
higher to main window};
#endif // INVOICEMODULEWINDOW_H
@invoicemodule.cpp
@#include "invoicemodulewindow.h"
#include "ui_invoicemodulewindow.h"
#include <QDebug>
InvoiceModuleWindow::InvoiceModuleWindow(QList<Invoice*> invoices, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::InvoiceModuleWindow)
{
//...
invoicess = invoices;
/here i get current invoices -> after i close this window and open it again it is empty thats why i need to store it higher so when i open it again i can redraw them on grid/
for(int invoice = 0; invoice < invoicess.size(); invoice++){
updateTable(invoices.at(invoice));
}
ui->tableView->setModel(model);}
InvoiceModuleWindow::~InvoiceModuleWindow()
{
delete ui;
for(int i = 0; i < invoicess.size(); i++)
{
delete invoicess.at(i);
}
}void InvoiceModuleWindow::on_actionClose_triggered()
{
this->close();
}void InvoiceModuleWindow::updateTable(Invoice* invoice)
{
int rowNumber = model->rowCount();QStandardItem *item = new QStandardItem(rowNumber,10); model->setItem(rowNumber,10,item); //... invoicess << invoice; //i update table here and i add new invoice...ofc i need to do the edit mechanics, but it is just basics
}
QList<Invoice*> InvoiceModuleWindow::getInvoices()
{
return invoicess; //this i want to return higher to main window
}
@ -
Perhaps you want to use an QObject as the head of your application. This object can keep a QList of main windows, and receive signals from a mainwindow to update all other windows. For instance
@MyObject : public QObject {
QList <QMainWindows> windowList;
slots:
void createNewWindowSlot();void invoiceChangedSlot(Inv *);
}
MyObject::createNewWindowSlot()
{
QMainWindow mw = new QMainWIndow(this);
connect(mw,SIGNAL(invoiceChanged(Inv)), this,SLOT(invocieCangedSlot(Inv*)));
windowList.append(mw);
}
MyObject::invoiceChangedSlot (Inv *){
{
QListIterator <QMainWindow *>iter(windowList);
while(iter.hasNext()) {
QMainWindow *mw = iter.next();
if (mw != (MainWindow *) sender())
mw->updateInvoice(inv)
}@Of course you will need to handle cases when a window is closed to remove it from the list.
This is what I have done for multiple windows that need some kind of synchronization. Hope it is of some value to you
}
-
Hi,
From your description, it seems that you should rather use the Model/View paradigm. Have a look at the corresponding chapter in Qt's documentation.
-
Hi and welcome to devnet.
the first thing is to use model/view that Qt has is very well done it. the second thing is why are you using 2 Main Windows? I mean you can update your main window's toolbars and menus... also why you do not use MDIarea and to do a MDI Application with only one mainWindow. in any way it is possible to do it but to be better organised in the beginning will be better in the future when your app will grow. having modules is very good but the structure of your app is not that good. in my idea is to have only one mainWindow this is why is called main -
Hey, sorry that i did not replay on Your messages, i just played around with my soft a little and i found a simple solution. Well tbh i decided to study slot and signals more depth and guess what, solution for my problem was very easy, let me put it here
I just created a simple connect between parent and child window
mainwindow.h
@public slots:
void onInvoiceModuleUpdate(Invoice* invoice);private:
InvoiceModuleWindow *invoiceModuleWindow;@invoicemodulewindow.h
@signals:
void onUpdate(Invoice* invoice);@i emit this signal in my update method (just for tests :D)
invoicemodulewindow.cpp
@void InvoiceModuleWindow::updateTable(Invoice* invoice)
{
int rowNumber = model->rowCount();QStandardItem *item = new QStandardItem(rowNumber,10); model->setItem(rowNumber,10,item); QModelIndex index = model->index(rowNumber,0,QModelIndex()); //..update stuff here emit onUpdate(invoice);
}@
then i connected it in mainwindow implementation
mainwindow.cpp
@void MainWindow::on_invoiceModule_clicked()
{
invoiceModuleWindow = new InvoiceModuleWindow(invoices, this);
invoiceModuleWindow->show();
connect(invoiceModuleWindow,SIGNAL(onUpdate(Invoice*)), this, SLOT(onInvoiceModuleUpdate(Invoice*)));
}void MainWindow::onInvoiceModuleUpdate(Invoice * invoice)
{
invoices << invoice; //there will be more advanced mechanics on update but u know, just for tests
}@I know that MVC would be a lot better, but for now MVC implementation in QT is a bit confusing for me so i searched for, maybe not gentle, but a simple way to solve my issue.
Thanks guys for Your replies, im looking forward to explore the forums more. I am having a blast with QT so i will stay here longer :)
You can mark this thread as solved. :)
-
to do this just edit your main post title and add [SOLVED] to it in the beginning