[Solved] Full MDI Example



  • It may seem silly, but I'm taking a beating for doing this.

    I need to open one within a QMdiSubWindow QMdiArea. The QMdiArea is part of a QMainWindow type window, this window I have some menus and submenus (QActions), when the user clicks on the QAction QMdiSubWindow should be opened within the QMdiArea.
    In QMdiSubWindow I will have some components like QLabel, QTextEdit, and a DataGrid QButton. I will also change the icon and title.

    As QMdiSubWindow have many components and modifications decided to create a class and inherit from QMdiSubWindow.

    If possible I would like friends to give an example with a QMainWindow that displays a menu containing a QMdiSubWindow. It would be nice if the example were created a class that inherits from QMdiSubWindow to be displayed within the QMdiArea.

    Sorry for asking so much but I have seen many examples on the internet but could not adapt.

    I looked at the example "Example MDI NOKIA":http://doc.qt.nokia.com/latest/mainwindows-mdi-mainwindow-cpp.html but in my case will not only have a widget like this example, will have several in my case as I mentioned above.

    Thanks guys!



  • Please don't use non-English language in non-national part of DevNet.



  • hi matheusssilva_BR,

    you just create a combined widget that you use a QMdiSubwindow, like you do with dialogs.



  • for example

    @#ifndef SUBWINDCLIENTES_H
    #define SUBWINDCLIENTES_H

    #include <QMdiSubWindow>

    class SubWindClientes : public QMdiSubWindow
    {
    public:
    SubWindClientes(QWidget *parent = 0, Qt::WindowFlags flags = 0);
    };

    #endif // SUBWINDCLIENTES_H
    @

    @#include "SubWindClientes.h"

    SubWindClientes::SubWindClientes(QWidget *parent, Qt::WindowFlags flags)
    {

    }@

    @#ifndef WINDOWMAIN_H
    #define WINDOWMAIN_H

    #include <QMainWindow>
    #include <QMdiArea>

    class WindowMain : public QMainWindow
    {

    public:
        WindowMain(QWidget *parent = 0);
    
        ~WindowMain();
    
    private:
        // Area MDI
        QMdiArea *mdiarea;
    
        // Menus
        QMenu *arquivos;
    
        // QActions de menus
        QAction *clientes;
    

    };

    #endif // WINDOWMAIN_H
    @

    @#include <QApplication>
    #include <QTextCodec>
    #include <QDesktopWidget>
    #include <QRect>
    #include <QMenuBar>
    #include <QToolBar> // Cabeçalhos da API Qt que serão usadas na janela pincipal
    #include <QStatusBar>
    #include <QList>
    #include <QLabel>

    #include "WindowMain.h" // Usa o arquivo de cabeçalho onde a classe foi definida

    /* Define a classe WindowMain e já invoca o
    construtor da classe pai, passando o ponteiro
    "parent" como parâmetro.*/

    WindowMain::WindowMain(QWidget *parent):QMainWindow(parent)
    {
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); // Define os caracteres da
    // aplicação p/ UTF-8

    setWindowTitle("Sistema Integrado de Gestão Óptica - MÓDULO RETAGUARDA");
    
    
    // Exibe a barra de status de QMainWindow
    statusBar()->show();
    
    // Prepara a area de trabalho MDI da aplicação
    mdiarea = new QMdiArea;
    setCentralWidget(mdiarea);
    
    
    // Prepara o menu principal da aplicação
    arquivos                        = menuBar()->addMenu("&Arquivo");
    
    
    // Prepara os itens de menu
    clientes                        = new QAction("Clientes", arquivos);
    
    // Carregando a lista de itens
    QList <QAction *> listarquivos;
    
    listarquivos << clientes;
    
    
    //Adicionando a lista de intens aos menus
    arquivos->addActions(listarquivos);
    
    // Deixando a janela no centro da tela
    QRect ct = geometry();
    ct.moveCenter(QApplication::desktop()->availableGeometry().center());
    setGeometry(ct);
    

    }

    WindowMain::~WindowMain()
    {
    delete mdiarea;
    }
    @

    How to open this QMdiSubWindow in this QMdiArea?



  • You can use the same logic as in the above mentioned example:

    @
    MdiChild *MainWindow::createMdiChild()
    {
    SubWindClientes *child = new SubWindClientes ;
    mdiArea->addSubWindow(child);
    return child;
    }
    @



  • When I run the application I get this output:

    Object:: connect: No such slot QMainWindow:: createMdiChild ()

    Below is the code:

    @#ifndef WINDOWMAIN_H
    #define WINDOWMAIN_H

    #include <QMainWindow>
    #include <QMdiArea>

    class WindowMain : public QMainWindow
    {

    public:
        WindowMain(QWidget *parent = 0);
    
        ~WindowMain();
    
    private slots:
        void createMdiChild();
    
    private:
        // Area MDI
        QMdiArea *mdiarea;
    
        // Menus
        QMenu *arquivos;
    
        // QActions de menus
        QAction *clientes;
    

    };

    #endif // WINDOWMAIN_H
    @

    @#include <QApplication>
    #include <QTextCodec>
    #include <QDesktopWidget>
    #include <QRect>
    #include <QMenuBar>
    #include <QToolBar> // Cabeçalhos da API Qt que serão usadas na janela pincipal
    #include <QStatusBar>
    #include <QList>
    #include <QLabel>

    #include "WindowMain.h" // Usa o arquivo de cabeçalho onde a classe foi definida
    #include "SubWindClientes.h"

    /* Define a classe WindowMain e já invoca o
    construtor da classe pai, passando o ponteiro
    "parent" como parâmetro.*/

    WindowMain::WindowMain(QWidget *parent):QMainWindow(parent)
    {
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); // Define os caracteres da
    // aplicação p/ UTF-8

    setWindowTitle("Sistema Integrado de Gestão Óptica - MÓDULO RETAGUARDA");
    
    
    // Exibe a barra de status de QMainWindow
    statusBar()->show();
    
    // Prepara a area de trabalho MDI da aplicação
    mdiarea = new QMdiArea;
    setCentralWidget(mdiarea);
    
    
    // Prepara o menu principal da aplicação
    arquivos                        = menuBar()->addMenu("&Arquivo");
    
    
    // Prepara os itens de menu
    clientes                        = new QAction("Clientes", arquivos);
    
    // Carregando a lista de itens
    QList <QAction *> listarquivos;
    
    listarquivos << clientes;
    
    
    //Adicionando a lista de intens aos menus
    arquivos->addActions(listarquivos);
    
    // Deixando a janela no centro da tela
    QRect ct = geometry();
    ct.moveCenter(QApplication::desktop()->availableGeometry().center());
    setGeometry(ct);
    
    connect(clientes, SIGNAL(triggered()), this, SLOT(createMdiChild()));
    

    }

    WindowMain::~WindowMain()
    {
    delete mdiarea;
    }

    void WindowMain::createMdiChild()
    {
    SubWindClientes *child = new SubWindClientes;
    mdiarea->addSubWindow(child);
    child->show();
    }
    @

    @#include "WindowMain.h"
    #include <QApplication>

    int main(int argc, char *argv [])
    {
    QApplication programa(argc, argv); // Objeto da aplicação

    WindowMain windmain;                 // Objeto da janela principal
    
    windmain.show();
    
    return programa.exec&#40;&#41;;
    

    }
    @

    Thanks for the help



  • your MainWindow misses the Q_OBJECT macro

    @
    #ifndef WINDOWMAIN_H
    #define WINDOWMAIN_H

    #include <QMainWindow>
    #include <QMdiArea>

    class WindowMain : public QMainWindow
    {
    Q_OBJECT;
    public:
    WindowMain(QWidget *parent = 0);

        ~WindowMain();
        // ...
    

    };

    #endif // WINDOWMAIN_H

    @



  • Thanks friend, now running.
    After I added the Q_OBJECT started giving an error

    / home / Matthew / Projects / Tests / WindowMain.cpp: -1: error: undefined reference to `vtable for WindowMain '

    To solve edited the project file:

    of

    @HEADERS +=
    SubWindClientes.h
    WindowMain.h

    SOURCES +=
    SubWindClientes.cpp
    WindowMain.cpp
    Main.cpp
    @

    to

    @HEADERS +=
    SubWindClientes.h
    WindowMain.h \

    SOURCES +=
    SubWindClientes.cpp
    WindowMain.cpp
    Main.cpp
    @

    Do not know why just adding these two backslashes solved the error.



  • [quote author="Denis Kormalev" date="1308946704"]Please don't use non-English language in non-national part of DevNet.[/quote]

    matheusssilva_BR, I repeat, you can write in Portuguese in the "Portuguese forum":http://developer.qt.nokia.com/forums/viewforum/34 .
    [pt_BR] Você pode escrever em Português no "fórum em Português":http://developer.qt.nokia.com/forums/viewforum/34 [/pt_BR]

    [quote author="matheusssilva_BR" date="1309010152"]
    Do not know why just adding these two backslashes solved the error.[/quote]

    No, the backslashes did not solve your problem.

    So, what happened?
    When you edited the .pro file, you forced an automatic execution of qmake before the next execution of make. (Actually, if your .pro file looks like what you posted above, with a backslash after the last file name, I expected an error...)

    Summing up: When you use the Q_OBJECT macro, the class has to be processed by moc (the Qt meta object compiler); in general qmake does it for you. This vtable error occurs when you add the Q_OBJECT macro and try to build the project without running qmake. For more details, "take a look here":http://doc.qt.nokia.com/4.7/metaobjects.html#meta-object-system



  • So what would be the solution? I just edit the code to compile and send any extra procedure should be done by Qt Creator.

    What to do now?


    As for the forum in Portuguese'll be honest with you, when I visited the forum in Portuguese completely lost the will to participate, there are hardly any topics and there are few who do not have the majority response.
    Truth be told Qt is widely used in Brazil and Portuguese-speaking countries.
    I believe that we can not wait a large participation of Brazilians there.

    Cursed be Cabral :-) |o|

    I do not use Qt as the enthusiast, student, etc.. Although it is now beginning to develop in Qt I use for professional development, then the help of the community is very important to me.



  • [quote author="matheusssilva_BR" date="1309015190"]So what would be the solution?
    [/quote]

    Run qmake when you add the Q_OBJECT macro.

    [quote author="matheusssilva_BR" date="1309015190"]
    I just edit the code to compile and send any extra procedure should be done by Qt Creator.
    What to do now?
    [/quote]

    Qt Creator automatically ran qmake for you when you edited the .pro file. I don't know if Creator can internally detect when the user adds a new Q_OBJECT macro to a file. I also think it would be good.

    In my previous post I explained to you that the backslash was not the solution.


    I agree with you, unfortunately the Portuguese forums aren't popular. I recommended it for you because:

    • you are a potential contributor to post things there;
    • "you mentioned the use of google translator":http://developer.qt.nokia.com/forums/viewthread/6978/ to write your posts. So, that's why I thought you would feel more comfortable writing in Portuguese there. Of course you are free to keep posting in the international forums, it was just a suggestion.

    Now it's better to stop this part of the discussion, as it is completely out of the scope of this thread.



  • So what you say is that this is not the most appropriate way to resolve are problems? So what would it be? Run qmake manually?

    The way I solved (by changing the .pro) can bring me any side effects?

    What I axei strange is that after I edited the .pro in this project, other projects that also emit the error adding Q_OBJECT, now emit no more, without me having to edit .pro them.



  • I'm not 100% sure, when creator runs qmake, it definitly does when you edit the .pro file. Sometimes (I'm not sure if always) changing the logic that is needed for makefiles (which are created by qmake) needs rebuild by hand.

    By hand means not to go to the command line, it means right click on the project --> rebuild.



  • Usually it's enough to just do "right click -> run qmake". If that doesn't work and I can't find the error I usually do a rebuilt (doesn't hurt once in while, especially, if you have generated files), too.



  • Ok, understood now, we won, was a big help


Log in to reply
 

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