Seite 1 von 1

[gelöst] QTabbedWidget: Es werden zu viele Tabs entfernt

Verfasst: 18. Dezember 2008 10:57
von M@g!ndo$ch
Hallo,

ich habe eine Klasse von QTabbedWidget abgeleitet und folgende Operationen neu implementiert:

Code: Alles auswählen



void OperationTabsContainer::mousePressEvent(QMouseEvent *pEvent)
{
	if(pEvent->button() == Qt::MidButton)
	{
		QPoint oPos = pEvent->pos();
		 
		QTabBar *pTabBar = this->tabBar();
		if(pTabBar != NULL)
		{			
			int iTabIdx = pTabBar->tabAt(oPos);
			if(iTabIdx != -1)
			{
				removeTab(iTabIdx);
			}
			else
			{
				LOG_ERROR_1("Could not determine TabIndex.");
			}
		}
		else
		{
			LOG_ERROR_1("Could not get TabBar.");
		}
	}
	else
	{
		//no need to handle event here
	}

	QTabWidget::mousePressEvent(pEvent);
}

int OperationTabsContainer::addTab(QWidget *pChild, const QString &oLabel)
{
	int iTabIdx = QTabWidget::addTab(pChild,oLabel);

	if(iTabIdx >= 0)
	{		
		m_oChildToRemoveMapper.setMapping(pChild,iTabIdx);
		m_oChildToUpdateMapper.setMapping(pChild,iTabIdx);
		bool bResult = false;	
		bResult = connect(pChild, SIGNAL(okBtnClicked()), &m_oChildToRemoveMapper, SLOT(map()));	
		bResult = connect(pChild, SIGNAL(attributeChanged()), &m_oChildToUpdateMapper, SLOT(map()));	
	}
	else
	{
		LOG_ERROR_1("Could not add tab.");
	}

	return iTabIdx;
}

void OperationTabsContainer::removeTab(int iIndex)
{
	QWidget *pWidget = widget(iIndex);
	if(pWidget != NULL)
	{
		OperationTab *pTab = static_cast<OperationTab*>(pWidget);
		if(pTab->getImplementationChanged() == true)
		{
			//TODO ask user if changes should be applied
		}

		delete pTab;

		QTabWidget::removeTab(iIndex);
	}
	else
	{
		LOG_ERROR_2("Could not get Widget at index ", static_cast<qint32>(iIndex));
	}
}
Dadurch möchte ich erreichen, dass man, wenn man mittels eines Clicks mit der mittleren Maustaste auf ein beliebiges Tab dieses Tab schließen kann. Das funktioniert soweit auch, allerdings wird nicht nur das gewünschte Tab, sondern auch das direkt rechts daneben geschlossen ^^. Also wenn ich z.B. 3 Tabs offen haben und auf das ganz linke klicke, wird dieses und das zweite von links geschlossen.

Kann mir bitte jemand erklären was ich falsch gemacht habe?

Gruß M@g

Verfasst: 18. Dezember 2008 13:37
von jerry42
Hallo,

also ich würde den Fehler irgendwo hier vermuten:

Code: Alles auswählen

delete pTab;
QTabWidget::removeTab(iIndex); 
Wieso ist das hier ein statischer Aufruf?

Ich bin mir nicht sicher wie das intern funktioniert und ob sich das auswirkt, aber du löschst zunächst das Objekt, und dann entfernst du nochmal das widget mit dem selben Index.
Und beim zweiten Aufruf steht dann das anfangs rechtsliegende Widget an der Index Position, wird also auch gelöscht.

So wäre der Fehler zumindest erklärbar.

Ich hoffe, es hilft.

Gruß jerry42

Verfasst: 18. Dezember 2008 14:07
von M@g!ndo$ch
Hmm,

du hast recht. Wenn ich QTabWidget::removeTab(iIndex); weg lasse funktioniert es.

Allerdings dachte ich, dass ich das machen muss da ich ja die Operation der Vaterklasse neu definiert habe. Ich war deshalb der Ansicht, dass ich die Operation der Vaterklasse nochmal explizit aufrufen muss damit das Tab entfernt wird, aber dem ist anscheinen nicht so.....

...Vielen Dank!

Verfasst: 18. Dezember 2008 14:50
von pfid
Ich wär mir nicht sicher, ob das auf Dauer so gesund ist. Wieso machst du nicht einfach

Code: Alles auswählen

tabWidget->removeTab(idx);

delete widget;
?

Verfasst: 18. Dezember 2008 15:31
von M@g!ndo$ch
Weil ich die Tab entfernen möchte, wenn mit der mittleren Maustaste darauf geklickt wird. Deswegen muss ich meine Klasse von QTabWidget ableiten um das Event abfangen zu können.

Verfasst: 18. Dezember 2008 15:53
von pfid
M@g!ndo$ch hat geschrieben:Weil ich die Tab entfernen möchte, wenn mit der mittleren Maustaste darauf geklickt wird. Deswegen muss ich meine Klasse von QTabWidget ableiten um das Event abfangen zu können.
Was hat das mit meiner Frage zu tun? ;)

Verfasst: 18. Dezember 2008 17:42
von M@g!ndo$ch
Äääääääähmmmmmm,

dein Vorschlage wäre ja nur realisierbar wenn die Klasse, die das Event (mittlere Maustaste gedrückt) behandelt, einen Zeiger auf das QTabWidget hätte. Allerdings ist es so, dass das Event von der von QTabWidget abgeleiteten Klasse ("OperationTabsContainer") behandelt wird. Und diese Klasse hat keinen Zeiger auf sich selbst (warum auch ^^).

Ich glaub wir reden aneinander vorbei ;-)

Verfasst: 18. Dezember 2008 17:50
von pfid
Du kannst doch die removeTab-Methode deiner Klasse aufrufen bevor du das Widget löscht, oder nicht?

Verfasst: 18. Dezember 2008 17:50
von franzf
Wenns bloß um den Mittelklick->remove geht, könntest du auch mit eventFilter arbeiten.
Dazu implementierst du in einer von QObject abgeleiteten Klasse die Methode eventFilter() ;)
Dies kannst du z.B. gleich in der "verwaltenden" GUI-Klasse machen, z.B. deinem MainWindow.

Verfasst: 18. Dezember 2008 18:44
von M@g!ndo$ch
Ich schaus' mir mal an.... danke!