QtStackedWidget - Calling Functions in MainWindow / Out Of Scope
-
Good Morning.
I have a Problem with QStackedWidget. The Situation is:
I have 1 QStackedWidget with 3 different Widgets: Each have their own UI (created in Designer).The Functions within the Widgets itself works as expected. The Problem is i.e:
1.) The Widget WebEngineView is open
2.) I call the Function to open a File in the Texteditor Widget (which works fine as this Function is called from within the Widget). But calling the Function "ChangeViewportToTextEditor" (which is in the MainWindow.cpp) after loading a File, does not work as it is out of Scope.Calling the Functions from the Menus directly work as expected.
How can I fix this? One nasty workaround is to connect the Document Changed with the Changeviewport Function: This works correctly but is obviously not a real Solution.
The Widgets did get created in the MainWindow.cpp. The Pointer in the MainWindow Header is correct.
Is there a working Solution with maybe the use of QThread:CurrentThread()?
Any hint is appreciated.
Thanks and have a great weekend everyone
Oliver -
Hi,
Your description is not really clear. Can you share your code ?
One point however is sure: QThread is innocent and should not get involved.
-
Evening. Here are some Code Snippets:
MainWindow.h:
</code>
#include "ctexteditor.h"namespace Ui {
class MainWindow;
}
//my classes
class CBrowser;
class CDatabase;
class CTextEditor;class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
friend class CBrowser;
friend class CDatabase;
friend class CTextEditor;private slots:
//Menu Entries for menuViewpoint
void switchViewpointBrowserOnly();
void switchViewpointTextEditorOnly();
void switchViewpointDatabaseOnly();private:
Ui::AKToolMainWindow *ui;//Main QStackedWidget to rule them all...
QStackedWidget *mainWindowStackedWidget;//The different Widgets for our Tool... CTextEditor *uiTextEditor; CBrowser *uiBrowser; CDatabase *uiDatabase; //Widgets which contains the Uis... QWidget *onlyTextEditor; QWidget *onlyDatabase; QWidget *onlyBrowser; //Different qGridLayout's for the different Viewpoints QGridLayout *showOnlyTextEditor; QGridLayout *showOnlyDatabase; QGridLayout *showDefaultStartupViewpoint; };
</code>
MainWindow.cpp:
<code>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::AKToolMainWindow)
{
//Own QStackedWidget for: Layouts, QMenu and everything else.
mainWindowStackedWidget = new QStackedWidget(this);//Different QWidgets for the different Layouts onlyBrowser = new QWidget(this); onlyTextEditor = new QWidget(this); onlyDatabase = new QWidget(this); //Add the QWidget's to mainWindowStackedWidget mainWindowStackedWidget->addWidget(onlyTextEditor); mainWindowStackedWidget->addWidget(onlyDatabase); mainWindowStackedWidget->addWidget(onlyBrowser); //Different qGridLayout's for different Viewports... showOnlyTextEditor = new QGridLayout(onlyTextEditor); showOnlyDatabase = new QGridLayout(onlyDatabase); showDefaultStartupViewpoint = new QGridLayout(onlyBrowser); //the different Uis / Widgets uiTextEditor = new CTextEditor(this); uiTextEditor->setObjectName(QString::fromUtf8("TextEditor :)")); uiDatabase = new CDatabase(this); uiBrowser = new CBrowser(this); //Add the specific Layouts to the GridLayout's... //Default Layout Settings at startup showDefaultStartupViewpoint->addWidget(uiBrowser,0,0); //0,1,1,1 //Database Viewpoint only showOnlyDatabase->addWidget(uiDatabase, 0,0); //OpenAntrag Viewpoint only //showOnlyOpenAntrag->addWidget(m_OpenAntrag, 0,0); //TextEditor Viewpoint only showOnlyTextEditor->addWidget(uiTextEditor, 0,0); //Set the Default Viewport [all Widgets are shown in the MainWindow] mainWindowStackedWidget->setCurrentWidget(onlyBrowser); //Set mainWindowStackedWidget->defaultStartupViewport as central Widget and activate it setCentralWidget(mainWindowStackedWidget); //Read saved Application Settings from ini File. //FIXME If first app start == true, create ini file with default settings... [we use a .ini file for easy backup and restore] readAppSettings(); createMenu(); //Activate MainLayout in mainWindowWidget mainWindowStackedWidget->show(); //BUG Nasty Workarounds for not working Stuff / switchingViewpoints etc. //connect(uiTextEditor->m_TextEditor,SIGNAL(textChanged()), this, SLOT(switchViewpointTextEditorOnly())); //connect(uiBrowser->m_BrowserModule,SIGNAL(loadStarted()), this, SLOT(switchViewpointDefaultBrowser())); qDebug() << "MainWindow Thread" << QThread::currentThread();
}
</code>How i.e. the TextEditor get Setup / Created:
CTextEditor.h:
<code>
class CTextEditor : public QWidget, public Ui::UIWidgetTextEditor
{
Q_OBJECT
public:
explicit CTextEditor(QWidget *parent = 0);
~CTextEditor();
friend class MainWindow;
};
</code>CTextEditor.cpp (Initial Part):
<code>
CTextEditor::CTextEditor(QWidget *parent) : QWidget(parent)
{
setupUi(this);
m_TextEditor->setFontPointSize(10);
m_TextEditor->setReadOnly(false);
m_TextEditor->document()->setModified(false);
}void CTextEditor::NewEmptyDocument()
{
mFileName = "";
m_TextEditor->document()->clear();
m_TextEditor->clear();
m_TextEditor->setText("");
m_TextEditor->setReadOnly(false);
MainWindow thisIsOfCourseOutOfScope;
thisIsOfCourseOutOfScope.statusBar()->showMessage("I want to reach the MainWindow but I am Out Of Scope");
//After creating a new empty File [and while another Widget is active / currently set], it should set the CTextEditor Widget as active...
thisIsOfCourseOutOfScope.switchViewpointTextEditorOnly();
}
</code>
[CBrowser and CDatabase are getting set up the same way]Thanks for any hint to correct my nonsense :)
-
First thing: don't do such tight coupling, Why would your editor need to know anything about your main window ?
Your use of friend smells like a bad shortcut to achieve what you want to do.
You should rather use signals and slots to communicate between your widgets and the main window. Take the time to take a look at Qt's examples in the documentation.
-
Yeah I know: Never use "friend" - use getter and setter. It is of course a nasty "workaround for now" to get me going.
I always thought, when it comes to Widgets, that it is bad design / bad coding? Should I really use connect() to access i.e. the StatusBar in the MainWindow from i.e. the CTextEditor Widgets in the Stack Widget?
-
If CTextEditor as something to transmit to the status bar, just make it emit the message and do the connection in MainWindow. CTextEditor should not care where the message goes, it's MainWindows responsibility to do something with it (or not)
-
Because of the Pointers and that Qt is C/C++ based, I always have in mind, that the i.e. CTextEditor should be aware of the Stuff in the MainWindow (can directly access the StatusBar and ToolBar because it is in the same Thread.) Seems I was wrong the whole time.
Thank you very much! I will have to completely rewrite and redesign a few things.
Greetings through the night :)
Oliver -
That's precisely what tight compiling is: too many classes knowing too much of each other. Maintenance nightmare in the making. Just one example with your current four classes, try to change MainWindow for something else: how much code do you have to modify with your current design ?
You're welcome !
Cheers -
Your Question was obviously rhetoric but:
As I am still a noob with Qt/C++ and a schizophrenic brain, it is hard to say how much I have to rewrite in the end. But luckily the whole Tool is still in you can say the "Alpha" Phase. Most of the Functions and Options are still missing.At this point I "only" have to redesign how things are getting set up and create the getters and setters along with the Signals and Slots (along with some If Statements for i.e. a Viewpoint is already active). The Standard things. But the longer I think about it, it sounds very nasty if I had to redesign and rewrite all the Stuff, that should have been done normally.
-
Well… In fact no, not rhetorical. But trust me, that will save you hours of pain later.