Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Replacing "MDI /area " text file management with managing ANY QtDesigner build subwindows



  • I am back to play with my project.
    I have it sort of working using dialogs and would like to "switch " to full mdi /area / subwindows concept.
    I had it partially working but it got too complicated using SUBDIRs and mutiprocessing.
    Now I am back to single process.
    So the "main" window / widget is "area " concept.
    The subwindows are managed * tile / cascade / resize etc. "using MdiChild class derived from QTextEdit.

    I like to retain the subwindows management by MdiChild class, BUT , be able to have the actual window based on QTDesiger widget , not just QTextEdit.
    At this point I do not need any "file" features.

    What would be the most reasonable way to implement this?

    I do not want to "code" the user interface, it needs to be implemented in QtDesigner - preferably as "TAB" widget. .

    EDIT

    I have found a useful article about multiple inheritance and it looks it may work for single ui form

    class CalculatorForm : public QWidget, private Ui::CalculatorForm

    I'll try that first and tackle variable forms later.

    Any other suggestions would be appreciated .



  • @AnneRanch
    You design the widgets you want to use on a QMdiSubWindow just like for any other widget you might use anywhere else, i.e. with their own .ui file and corresponding .cpp./.h.

    You always have 3 choices for how to use a designed-widget:

    1. Simply create and add it into your UI at run-time, e.g. mdiSubWindow->addWidget(new MyWidget). So no Designer support.

    2. Use Designer's Promote. You can now add a MyWidget as a widget like the in-built ones in Designer. If, say, MyWidget is derived from QTextEdit it will look like a QTextEdit at design-time and have QTextEdit's properties as editable in Designer. But not any looks/properties you may have added.

    3. Create a custom widget and register that with Designer. Its look/properties at design-time will be fully what it is at runtime. But this is a lot more work.



  • @JonB Thanks
    I thing I can do it.
    The "problem" is that MDI example does more than just "add subwindow" .
    And its subwindow is fixed as ":text edit" .
    I need to keep the managing part and replace the "text edit " with forms from QtDesigner.



  • @AnneRanch said in Replacing "MDI /area " text file management with managing ANY QtDesigner build subwindows:

    The "problem" is that MDI example does more than just "add subwindow" .

    I know. From your previous posts on this matter, and where you write above

    At this point I do not need any "file" features.

    I have seen you talking about this "File" aspect before in your questions on MDI. MDI has nothing to do with that "File" stuff per se. In the example from which you work they chose to write an MDI app, such that each MDI window corresponded to: put a QTextEdit on the MDI child window, read in a file, use that filename as the MDI child window title, allow you to edit, save the file back. All of that is just what they chose to do in their example code. It's not inherently MDI. You don't have to do any of that stuff in your own usage.

    An MDI child window shows any one top-level widget. It could be their QTextEdit. It could be a generic a QWidget. It could be your own widget derived from QWidget. Including any widget you design in Designer.



  • @JonB Looks like you have been "reading the mail" .

    AS I said before - the MDI example is exactly what you have summarized.
    Their "MDI" is text editor WITH associated file processing.
    I have tried to change the text editor to plain widget but it breaks the "file processing " big time. . So it is a matter of choice - bypassing all the "file processing " error as they come up or try to ADD / replace the internal QTextEdit place usage of what is left AFTER the title bar.
    It seems less painful to reuse QTextEdit ,specially when it is derived from QWidget already. QTextEdit is pretty versatile , it is capable of displaying "image" so why not TAB widget? It should be just matter of " taking over" the "text window" .



  • @AnneRanch
    You won't be able to get any kind of tab widget into a QTextEdit I'm afraid. It will display plain text or HTML text and images, but that's all.

    The truth is that I know you want to work from that MDI example. You could indeed have your own QTabWidget, say, instead of the QTextEdit on your MDI window. But you really need to get rid of their QTextEdit, and all the code which goes with it to do with editing and saving a file, before you will progress in your direction. That either means stripping it out starting from the example, or starting afresh not from the example and putting new stuff back in.



  • @AnneRanch I am sorry but I fail to grasp the difficulty you face.
    I wrote literally one MDI application in my life, for representing data from a set of serial devices (each MDI child per device) - I just designed the parameter MDI child in the designer (simply add UI class with QWidget as the ancestor), filled in whatever functionality I wanted in the MDI child window and (simplified code):

    mdiArea.addSubWindow(new MyMdiChildClass(),flags);
    

    Current window can be recovered easily, I experimented also for a while with storing the return QMdiChildWindow*...
    My point is - you can design any form based on QWidget and it will just work?

    I am sorry if I sound silly here but I really don't understand your problem.



  • @JonB I selected MDI example because it actually manages the subwindows - tile / cascade etc.
    As I said before - unfortunately the subwindows are
    QTextEdit and associated file processing.
    I find it not that easy to just "replace QTextEdit with QWidget".
    I am not making any excuses for my lack of skills, but navigating flow of MDI example which lacks ANY documentation is at this point "a learning experience". It will just take more time...



  • @artwaw See my last post.
    I do not have many issues putting any widget as subwindow , it is the MDI example managing these subwidnows.



  • @AnneRanch
    I take it you have copied from https://doc.qt.io/qt-5/qtwidgets-mainwindows-mdi-example.html. (I don't take the sample files supplied with the Qt distribution which is what you do, but I believe what you have is exactly what is at that web link).

    Literally some 90% of that code is not what you want. The vast majority is all to do with the specifics of their example, which is to have a QTextEdit and allow a file to be opened, read in, edited and saved. It simply is irrelevant/not wanted once you want to do you own thing with MDI windows.

    • You do not want anything which is in mdichild.cpp/.h. Literally all you do want is the sole:
    MdiChild::MdiChild()
    {
        setAttribute(Qt::WA_DeleteOnClose);
    }
    
    • You probably don't want what's in mdi.qrc.

    • From mainwindow.cpp/.h you want MainWindow::MainWindow() & MainWindow::closeEvent(QCloseEvent *event).

    • You can keep MainWindow::about(). You want some of what's in MainWindow::updateMenus(), MainWindow::updateWindowMenu(), MainWindow::createMdiChild(), MainWindow::createActions().

    • You might want MainWindow::readSettings() & MainWindow::writeSettings(). MainWindow::findMdiChild() is a useful utility.

    • From main.cpp you don't want the QCommandLineParser lines,

    And that's about it! Basically anything & everything that mentions "file" --- which is most of the code --- is not for you. Nor anything about "copy" or "clipboard". Even the stuff about saving/loading "settings" is optional, you don't need it. There's really maybe 100 lines from all this you actually want!

    On the doc page https://doc.qt.io/qt-5/qmdiarea.html#addSubWindow they show:

        QMdiArea mdiArea;
        QMdiSubWindow *subWindow1 = new QMdiSubWindow;
        subWindow1->setWidget(internalWidget1);
        subWindow1->setAttribute(Qt::WA_DeleteOnClose);
        mdiArea.addSubWindow(subWindow1);
    
        QMdiSubWindow *subWindow2 =
            mdiArea.addSubWindow(internalWidget2);
    

    That is the skeleton of how you add QMdiSubWindows to a QMdiArea mdiArea. (They are alternatives: for your purposes you don't need the 4 line way they add subWindow1, you can do it with just the single line way they add subWindow2!) You could replace internalWidget1/2 with anything derived from QWidget, including say QTabWidget or your own specialized QTabWidget which you design standalone in Designer with whatever you want on it to produce its own .ui/.cpp/.h file. And then just some code for a QMenu with some QActions which allow you to open the subwindows, assuming you don't just want them all open all the time without closing them.

    I had a look around. I came across Qt/C++ - Tutorial 063. Adding windows inside the main application window using QMdiArea. That has 27 lines in mainwindow.h and 42 lines in mainwindow.cpp. They don't supply it, but I think their mainwindow.ui (the file saved from Qt Designer) is nothing but a QMainWindow named MainWindow, plus a QMenu with a QAction named actionAddWindow. If you look at this and understand just what they have there you have most of what you need for an MDI application.



  • @JonB Thanks, very nice and useful info , but about three months late.
    I got rid of the "MDIChild" class, IMHO poor implementation of creating subwindows.
    I am now at the point to analyze the area management code ( tile etc.)
    I got sidetracked by fiddling with "menu" and touch of "lambda" .
    Years ago I try "passing function as parameter" and just found that "connect" has strange way to deal with passing parameters to such function.

    I appreciate all the references, unfortunately I subscribe to
    " 80 % task description, comments, trace , QDebug IN CODE ,
    20 % code".

    MDI example is 0 % comments - but I am repeating myself , again.

    I do miss IBM flowcharts...but that is my fault - I dropped my interest in "graph" - similar to Eclipse.
    I wish somebody would figure out how to extend "hierarchy" feature.
    Live and learn...



  • Serious question.
    MDI example used "MDIChild ' class derived from "Text edit widget" to specifically manage "file" child / subwindow.

    If I want to "simplify / make generic" my replacement for MDICHild class - what would be reasonable , if any base class / classes to use?

    My goal is to emphasize the management of subwindows and not what is being managed.

    BTW I finally realized ONE minor part of difficulties I have been having with MDI example , a real minor one.

    MDI example manages the "area subwindows " (area terminology ) but the managing class in named "child ".
    ( OK , I am being picky )



  • @AnneRanch QWidget or almost any descendant of QWidget since QMdiArea::addSubWindow() requires QWidget.



  • @AnneRanch
    As @artwaw has said. In that example mdichild.h has class MdiChild : public QTextEdit. If you replaced that with, say, class MdiChild : public QTabWidget you would be making the top-level widget of the subwindow be the tab widget you talked about wanting. Of course you would then have to make other changes in mdichild.h/.cpp to reflect that change.


Log in to reply