Seite 1 von 1
QMainWindow als central widget in einem anderen QMainWindow
Verfasst: 4. Januar 2008 14:07
von dynamo
Hallo.
Vielleicht kann mir jemand helfen. Ich habe folgendes Problem.
Ich habe ein MainWindow „Main“ und ein tool bar in diesem MainWindow mit zwei tool buttons „A“ und „B“. Außerdem habe ich zwei weitere MainWindows „A“ und „B“.
Im Konstruktor von „Main“ setze ich als central widget main window „A“. Wenn ich die Anwendung starte, wird vom Anfang an das main window „A“ in einem main window „Main“ angezeigt.
Durch das Anklicken des Buttons „B“ wird als central widget das main window „B“ gesetzt und angezeigt.
Und jetzt kommt der Fehler. Wenn ich durch das Anklicken des Buttons „A“ mein main window „A“ nochmals als central widget setzen und anzeigen will, stürzt die Anwendung ab.
Wenn ich das Button „A“ anklicke soll main window „A“ in main window „Main“ als central widget gesetzt werden, und wenn ich das Button „B“ anklicke, soll main window „B“ in main window „Main“ als central widget gesetzt werden.
Leider kann ich den Fehler, der zu dem Absturz führt, nicht finden.
Ich wäre sehr dankbar, wenn jemand mir hilft.
Vielen Dank im Voraus.
Verfasst: 4. Januar 2008 14:53
von solarix
Was genau (code!) wird ausgefuehrt, wenn der Button "A" angeklickt wird?
Verfasst: 4. Januar 2008 15:14
von dynamo
Hi Solarix, danke für deine Antwort.
Das ist ein Codeausschnitt:
Code: Alles auswählen
void QtLiborMainWindowComp::initializeGui()
{
BaseClass::initializeGui();
// main window "A" vom Anfang an als central widget setzen:
onSetMainWindowComponen(m_liborCalibrationMainWindowComp.getInterface());
// connections:
connect(actionCalibration, SIGNAL(toggled(bool)), this, SLOT(onShowCalibrationMainWindow(bool)));
connect(actionPricing, SIGNAL(toggled(bool)), this, SLOT(onShowPricingMainWindow(bool)));
connect(this, SIGNAL(setMainWindowComponent(const acf::QtGuiInterface*)), this, SLOT(onSetMainWindowComponent(const acf::QtGuiInterface*)), Qt::QueuedConnection);
}
// tool button A:
void QtLiborMainWindowComp::onShowCalibrationMainWindow(bool show)
{
setActionUnchecked(actionPricing, show);
emit setMainWindowComponent(m_liborCalibrationMainWindowComp.getInterface());
}
// tool button B:
void QtLiborMainWindowComp::onShowPricingMainWindow(bool show)
{
setActionUnchecked(actionCalibration, show);
emit setMainWindowComponent(m_liborPricingMainWindowComp.getInterface());
}
// setzt entwedr main window "A" oder main window "B" als central widget:
void QtLiborMainWindowComp::onSetMainWindowComponent(const acf::QtGuiInterface* guiPtr)
{
if (guiPtr != NULL){
QWidget* widgetPtr = dynamic_cast<QWidget*>(guiPtr->widget());
if (widgetPtr != NULL){
qtWidget()->setCentralWidget(widgetPtr);
}
}
}
// tool buttons aktivieren/deaktivieren:
void QtLiborMainWindowComp::setActionUnchecked(QAction* action, bool show)
{
action->blockSignals(true);
action->setChecked(!show);
action->blockSignals(false);
}
Verfasst: 4. Januar 2008 15:27
von solarix
ich seh noch nicht so ganz, wie du deine Objekte verwaltest (m_liborCalibrationMainWindowComp.getInterface())), aber sowas in der Richtung dachte ich mir...
Code: Alles auswählen
emit setMainWindowComponent(m_liborPricingMainWindowComp.getInterface());
Hast du bedacht, dass:
void QMainWindow::setCentralWidget ( QWidget * widget )
Note: QMainWindow takes ownership of the widget pointer and deletes it at the appropriate time.
das Widget vom QMainWindow geloescht wird? Beim 2. setCentralWidget (Button "B") wird das erste

MHO) wieder freigegeben...
Verfasst: 4. Januar 2008 15:54
von dynamo
Ja klar, ich habe daran gedacht und das, was du geschrieben hast, auch gelesen im Qt- Assistant. Aber das bedeutet, dass der Widget-Zeiger zur
passenden Zeit gelöscht wird. Und ich bin nicht sicher, dass erster Zeiger auf Widget "A" beim zweiten Aufruf von setCentralWidget gelöscht wird.
Wenn ich im initializeGui()
Code: Alles auswählen
// main window "A" vom Anfang an als central widget setzen:
onSetMainWindowComponen(m_liborCalibrationMainWindowComp.getInterface());
beispielsweise 5 Mal nacheinander aufrufe, dann kommt es nicht zum Absturz.
Also, du bist der Meinung, dass es wirklich so ist?
Verfasst: 4. Januar 2008 16:04
von solarix
dynamo hat geschrieben:
Also, du bist der Meinung, dass es wirklich so ist?
ja.. denn ich wuerde sagen, bei "setCentralWidget()" is es "passend" (das andere Widget wird ja nicht mehr benoetigt..)
Dass du beim Start 5x hintereinander diese Operation machen kannst ist nicht unwahrscheinlich... Es wird in dieser Zeit ja nichts mit dem (nun freigegeben) Speicher gemacht...da sind noch alle Daten vorhanden... erst spaeter, wenn neuer Speicher (von dir, Qt oder sonst wem) angefordert wird, wird der Bereich ueberschrieben (und damit bei falscher Verwendung wie setCentralWidget() ein Crash provoziert)
Verfasst: 4. Januar 2008 16:08
von dynamo
Danke solarix