Seite 1 von 1

Widget in einem DockWidget ersetzen?

Verfasst: 15. September 2006 17:26
von Anton
In einem QDockWidget wird die Eigenschaft eines Dokuments in Form eines QTreeWidget angezeigt. In einer MDI-Anwendung soll die Eigenschaft des jeweils aktiven Dokuments im selben QDockWidget angezeigt werden.

Der Titel, die Position und die Sichbarkeit des DockWidget soll dabei erhalten bleiben. Deshalb wird nur ein DockWidget im MainWindow angelegt, das von allen Dokumenten abwechselnd genutzt werden soll.

Code: Alles auswählen

class MdiChild : public QTextEdit
{
.
.
public:
	ParameterTree *equipment;
.
.
};

class MainWindow : public QMainWindow
{
.
.
	QDockWidget *dockWdgtEqmt;

	QDockWidget *getDockWdgtEqmt(){return dockWdgtEqmt;}
	void createDockWindows();
	void replaceEquipment(ParameterTree* equipment = 0);
.
.
};

void MainWindow::createDockWindows()
{
	dockWdgtEqmt = new QDockWidget(tr("Equipment"), this);
	dockWdgtEqmt->setObjectName("DW_0");
	dockWdgtEqmt->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
	addDockWidget(Qt::RightDockWidgetArea, dockWdgtEqmt);
}
In jedem Dokument wird ein von QTreeWidget abgeleiteter ParameterTree angelegt, dessen Parent-Widget das DockWidget ist.

Code: Alles auswählen

MdiChild::MdiChild()
{
 	equipment = new ParameterTree(theMainWin->getDockWdgtEqmt());
}
Sobald ein Dokument geladen wird, wird der ParameterTree (equipment) in das DockWidget (dockWdgtEqmt) gesetzt:

Code: Alles auswählen

bool MdiChild::loadFile(const QString &fileName)
{
    QFile file(fileName);
    if (file.open(QFile::ReadOnly | QFile::Text)) {
	equipment->read(&file);
	theMainWin->replaceEquipment(equipment);
     }
.
.
    return true;
}

void MainWindow::replaceEquipment(ParameterTree* equipment)
{
	ParameterTree* old = qobject_cast<ParameterTree*>(dockWdgtEqmt->widget());
	if (equipment != old) {
		dockWdgtEqmt->setWidget(equipment);
		dockWdgtEqmt->update();
	}	
Die Eigenschaft des jeweils zuletzt geladenen Dokuments wird wie erwartet im DockWidget angezeigt. Wird aber ein zuvor geladenes Dokument aktiviert, dann wird dessen "equipment" mit setWidget(equipment) in das DockWidget gesetzt.

Code: Alles auswählen

void TabWorkspace::updateMainWin(int index)
{
	MdiChild *mdiChild = qobject_cast<MdiChild *>(QTabWidget::widget(index));
	if (mdiChild)
	{
		theMainWin->setWindowTitle(mdiChild->pageTitle());
		theMainWin->replaceEquipment(mdiChild->equipment);
	}
}
Der Titel in MainWindow wird richtig gesetzt, aber im DockWidget wird immer noch die Eigenschaft (QTreeWidget) des zuletzt geladenen Dokuments angezeigt.
Wenn man nun das DockWidget vergrößert, ändert sich die Größe des QTreeWidgets des zuvor geladenen Dokuments dahinter, die Größe es zuletzt geladenen bleibt unverändert.

Es hat den Anschein, als ob mit QDockWidget::setWidget(QWidget*) das zuvor gesetzte Widget nicht, oder nur teilweise entfernt wird. In der Doku von Trolltech habe ich keinen Hinweis gefunden, dass dieser Aufruf nur einmal verwendet werden darf.

Ich bin für jeden Hinweis dankbar.
Anton

Verfasst: 16. September 2006 14:19
von Anton
Den Hinweis dieses Problem in den Griff zu bekommen, erhielt ich im Qt Centre Forum: Nur eines der QWidgets, die in das QDockWidget gesetzt werden, darf das QDockWidget als Parent besitzen.

Mit drei Zeilen Code ist das ausgebüglt:

Code: Alles auswählen

void MainWindow::replaceDockEquipment(ParameterTree* equipment)
{
	ParameterTree* old = qobject_cast<ParameterTree*>(dockWdgtEqmt->widget());
	if (equipment != old) {
		if (old)
			old->setParent(0);	// in memorial yogeshm02 (Qt Centre Forum)

		equipment->setParent(dockWdgtEqmt);
		dockWdgtEqmt->setWidget(equipment);
	}	
}
Ich hoffe diese Lösung ist eine Hilfe für die alle, die sich in dieses Problem vertieft haben, wofür ich mich herzlich bedanke.