PDA

View Full Version : trouble with the QAction and Signal/Slot-system



doktorn
17th November 2007, 17:17
Hello,
I have a little trouble with the QAction and Signal/Slot-system. How do I tell what QAction was just activated(triggered) when I'm already "sent on" to the SLOT-function?


#include <QtGui>

#include "mainwindow.h"

MainWindow::MainWindow()
{
setupUi(this);

connect(pushButton, SIGNAL(clicked()), this, SLOT(pushButton_clicked()));

userCounter=0;
}

//Read files from users-directory (every user is represented by the filename in a file)
//Add the filenames to a array of Action-pointers
//Make a connection with the Action and the edit-user function(slot)
void MainWindow::pushButton_clicked()
{
QDir dir;
dir.setPath("users");
QStringList userFiles = dir.entryList(); //gets the filelist from the users-dir
userFiles.removeFirst(); //Removes the . entry
userFiles.removeFirst(); //Removes the .. entry

//Make Actions and send em to the menu until the StringList is empty
while(!userFiles.isEmpty()){
userAction[userCounter] = new QAction(userFiles.takeFirst(), this);
menuUser->addAction(userAction[userCounter]);
connect(userAction[userCounter], SIGNAL(triggered(), this, SLOT(editUser()));
userCounter++;
}
}

void MainWindow::editUser()
{
//textLabel is just a label in the mainwindow - so i can see if i reach this function
textLabel->setText("One has been triggered - my problem is to tell which one");
}

So, I click the "pushButton" and voila - the menu gets filled up.
I choose one of the users from the menu - and voila - the textLabel is updated.

However - I need to know, being in the editUser-function, what user to change. that is - what Action OR what menuoption was triggered - what is the text of that menu-option (a.k.a. the userfilename)?

I have tried to work a little with sending QAction-pointers along to the editUser-function, without any working result. And even if I get that to work - how do i extract the "username" in a smart way from the QAction in question?

Any solutions to this problem - or Work-arounds to make the same thing happen in a different way would be appreciated.

mcosta
18th November 2007, 09:41
Hi,

you can use QObject::sender() to get the sender of a slot.

See also class QSignalMapper

jpn
18th November 2007, 09:58
QActionGroup is also one option.

doktorn
19th November 2007, 15:31
Very Nice. I went with the QActionGroup this time, but the other info was also very helpful.
Thanks to both of you mcosta and jpn.

I post my working code - in case somebody has the same problem. (And yes, I fertilize my code with too many comments :p )



#include <QtGui>

#include "mainwindow.h"

MainWindow::MainWindow()

{
setupUi(this);
connect(pushButton, SIGNAL(clicked()), this, SLOT(pushButton_clicked()));
userCounter=0; //sets users to 0 at creation of each mainwindowobject (we only have one - so its in reality a static int)
}

void MainWindow::pushButton_clicked() //here a filereding from the user-dir will take place
{
QDir dir;
dir.setPath("users");
QStringList userFiles = dir.entryList(); //gets the filelist from the users-dir
userFiles.removeFirst(); //Removes the . entry
userFiles.removeFirst(); //Removes the .. entry

actionGroup = new QActionGroup(this); //Makes a alignmentgroup of the actions so that we can identify which one has been chosen

while(!userFiles.isEmpty()){
userAction[userCounter] = new QAction(userFiles.takeFirst(), this); //adds the first userFile-entry to a userAction-entry
userAction[userCounter]->setCheckable(true); //The action must be set checkable so we can check this status later on
actionGroup->addAction(userAction[userCounter]); //adds the userAction-entry to the actionGroup
menuUser->addAction(userAction[userCounter]); //adds the userAction-entry to the usermenu
connect(userAction[userCounter], SIGNAL(triggered()), this, SLOT(editUser()));
userCounter++;
}
}
void MainWindow::editUser() //temporary function that will be replaced with the real edituser-program
{
QAction * tmp = actionGroup->checkedAction();
if (tmp==0) textLabel->setText("Bad Data");
else {
textLabel->setText(tmp->text()); //try out the username (tmp) by displaying it on textLabel
}
}