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 aQMdiSubWindow
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:
-
Simply create and add it into your UI at run-time, e.g.
mdiSubWindow->addWidget(new MyWidget)
. So no Designer support. -
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 fromQTextEdit
it will look like aQTextEdit
at design-time and haveQTextEdit
's properties as editable in Designer. But not any looks/properties you may have added. -
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 aQWidget
. It could be your own widget derived fromQWidget
. 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 aQTextEdit
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 theQTextEdit
on your MDI window. But you really need to get rid of theirQTextEdit
, 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... -
@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 wantMainWindow::MainWindow()
&MainWindow::closeEvent(QCloseEvent *event)
. -
You can keep
MainWindow::about()
. You want some of what's inMainWindow::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 theQCommandLineParser
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
QMdiSubWindow
s to aQMdiArea mdiArea
. (They are alternatives: for your purposes you don't need the 4 line way they addsubWindow1
, you can do it with just the single line way they addsubWindow2
!) You could replaceinternalWidget1
/2
with anything derived fromQWidget
, including sayQTabWidget
or your own specializedQTabWidget
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 aQMenu
with someQActions
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 inmainwindow.cpp
. They don't supply it, but I think theirmainwindow.ui
(the file saved from Qt Designer) is nothing but aQMainWindow
namedMainWindow
, plus aQMenu
with aQAction
namedactionAddWindow
. If you look at this and understand just what they have there you have most of what you need for an MDI application. - You do not want anything which is in
-
@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 examplemdichild.h
hasclass 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 inmdichild.h
/.cpp
to reflect that change.