[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_OBJECT

    public:
    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_OBJECT

    public:
    explicit InvoiceModuleWindow(QList<Invoice*> invoices, QWidget parent = 0);
    ~InvoiceModuleWindow();
    QList<Invoice
    > getInvoices(); //method that returns invoices

    private:
    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
    }
    @



  • to delete :)



  • Can you cut down the sample to just what's needed to demonstrate the issue? It doesn't sound like a difficult problem to solve, but reading through the volume is discouraging.



  • Ok, ill do it when im back home, thanks for Your interest.



  • I cut the useless code so i hope it is more clearly, sorry for the previous, i hope You can help me :). Thanks in advance.



  • 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

    }


  • Lifetime Qt Champion

    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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.