Seite 1 von 1

[gelöst] [Qt4] mehrere QActions mit einem Slot verbinden

Verfasst: 22. September 2005 09:48
von macman
Moin,

ich versuche gerade einer Applikation im Filemenü die zuletzt genutzten Dateien hinzuzufügen. Mit Qt3 war das einfach, bei Qt4 gibt es ein Problem. Die einzelnen Menüpunkte bestehen aus QActions und ich kann sie auch einem Slot zuweisen, nur, wie stelle ich im Slot fest, von welchem QAction das jetzt getriggert wurde? Hier mal ein Stückchen Code:

Zuerst das Menü jedesmal neu aufbauen:

Code: Alles auswählen

//////////////////////////////////////////////////////////////////////////
// Menu with recent files
void MainWindow::updateFileMenu()
{
	fileMenu->clear();
	fileMenu->addAction(newFileAction);
	...
	...

	if (m_slRecentFiles.count()>0)
	{
		fileMenu->addSeparator();
		for ( int i=0; i<m_slRecentFiles.count(); ++i ) 
		{
			if (recentFileAction[i]!=NULL)
				delete recentFileAction[i];
			recentFileAction[i] = new QAction(QString("&%1 " + m_slRecentFiles[i]).arg(i), this);
			connect(recentFileAction[i], SIGNAL(triggered()), this, SLOT(OnOpenRecentFile()));
			fileMenu->addAction(recentFileAction[i]);
		}
	}
}
Das funktioniert problemlos, es wird auch der folgende Slot aufgerufen:

Code: Alles auswählen

//////////////////////////////////////////////////////////////////////////
// Call of one of the recent files
void MainWindow::OnOpenRecentFile()
{
	QAction* action = fileMenu->activeAction();
	if (action==NULL)
		return;

	// do what to do
}
action ist immer NULL. Hab ich was vergessen, übersehen? Den Support von Trolltech habe ich inzwischen angeschrieben, aber das dauert manchmal bis die antworten und es drängt etwas.

Wenn ich Antwort habe, werde ich es auf jeden Fall hier kundtun, denn IMHO funktioniert hier was nicht oder es fehlt was.

Verfasst: 22. September 2005 10:24
von kowi1134
Beim Slot habe ich festgestellt, dass Du auf dein QMenu ("fileMenu") die Methode activeAction aufrufst. In der Doku steht aber
Qt hat geschrieben:Returns the currently highlighted action, or 0 if no action is currently highlighted.
Da Dein slot aber aufgerufen wird, nachdem Du bereits GEKLICKT hast, ist die entsprechende QAction auch nicht mehr "gehighlighted".

Als Ausweg schlage ich vor, Du versuchst es mal mit dieser Funktion:
Qt hat geschrieben:void QMenu::triggered ( QAction * action ) [signal]

This signal is emitted when a menu action is triggered; action is the action that caused the signal to be emitted.

Normally, you connect each menu action's triggered() signal to its own custom slot, but sometimes you will want to connect several actions to a single slot, for example, when you have a group of closely related actions, such as "left justify", "center", "right justify".
Damit verlagerst Du das Problem, welche Action aufgerufen wurde einfach auf eine Ebene höher, also auf das Menu.

D.h. Du bekommst in Deinem slot die entsprechende Action direkt übergeben. Sofern in Deinem Menu allerdings noch andere Actions hast, wäre es an Dir, zu überprüfen, ob die aktuelle Action sich auf eine zuletzt geöffnete Datei bezieht.

Verfasst: 22. September 2005 10:58
von macman
kowi1134 hat geschrieben:Da Dein slot aber aufgerufen wird, nachdem Du bereits GEKLICKT hast, ist die entsprechende QAction auch nicht mehr "gehighlighted".
Sowas hab ich mir auch schon gedacht. Ich hab auch schon einiges probiert und es eigentlich nur drin stehen lassen, um das Problem besser zu verdeutlichen.
Qt hat geschrieben:void QMenu::triggered ( QAction * action ) [signal]
Auch das hatte ich schon probiert, aber falsch implementiert, deshalb ging es nicht :)
Der connect darf nicht so

Code: Alles auswählen

        connect(recentFileAction[i], SIGNAL(triggered(QAction*)), this, SLOT(OnOpenRecentFile(QAction*)));
aussehen, sondern muß so

Code: Alles auswählen

        connect(fileMenu, SIGNAL(triggered(QAction*)), this, SLOT(OnOpenRecentFile(QAction*)));
lauten. Aus der Schleife muß er natürlich auch raus. Jetzt wird der Slot zwar bei jedem Klick aufgerufen, aber das kann man ja unterscheiden.

Danke für den Tipp, sonst hätte ich es mir wohl nicht noch mal angeschaut.