Widget in einem DockWidget ersetzen?

Alles rund um die Programmierung mit Qt
Antworten
Anton
Beiträge: 9
Registriert: 27. Juli 2006 13:11
Wohnort: Asperg

Widget in einem DockWidget ersetzen?

Beitrag 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
Qt Desktop Edition - Plattform: Windows - Version: 4.3.0
Anton
Beiträge: 9
Registriert: 27. Juli 2006 13:11
Wohnort: Asperg

Beitrag 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.
Qt Desktop Edition - Plattform: Windows - Version: 4.3.0
Antworten