What's wrong with my actions???
In a custom tree model I have enabled context menu handling at node level and the code looks like that :
Code:
pMenu
= new QMenu("Actions");
setupMenu(pMenu);
qDebug("action triggered : %s", a ? qPrintable(a->text()) : "");
//pMenu->deleteLater();
if ( a )
a->trigger();
setupMenu() is a virtual function that is in charge of setting up the menu content :
Code:
connect(a , SIGNAL( triggered() ),
this, SLOT ( deleteLater() ) );
m->addAction(a);
m->addSeparator();
a
= new QAction(QIcon(":/folder.png"), tr
("A&dd folder"), m
);
connect(a , SIGNAL( triggered() ),
this, SLOT ( addFolder() ) );
m->addAction(a);
connect(a , SIGNAL( triggered() ),
this, SLOT ( addFile() ) );
m->addAction(a);
connect(a , SIGNAL( triggered() ),
this, SLOT ( newFile() ) );
m->addAction(a);
m->addSeparator();
connect(a , SIGNAL( triggered() ),
this, SLOT ( clear() ) );
m->addAction(a);
When I play with my model on a QTreeView the context menu gets displayed correctly. Then if I trigger an action by clicking on a menu item I get a correct message on the console output ( i.e : "action triggered : x") but the triggered signal is never emitted (or never forwarded to the slots I have connected to it even when I call trigger() programmatically ...
I'm using Qt 4.2.2 under Linux. Any hints???
Re: What's wrong with my actions???
What is "this" in setupMenu()? What method you invoke "setupMenu(pMenu);" from?
Re: What's wrong with my actions???
I have a node (the typename doesn't matter here) inheriting from QObject. It has a void contextMenuEvent(const QPoint& p) called from the view (first block of code) and the setupMenu() is also a member of this class. The puzzling thing is that I tried substituting signal/slots with QMetaObject::invokeMethod but it did not give any result either...:(
EDIT :
Yeah!!! I've solved it! My fix is (very) dirty but inheritance-aware as I needed and AFAIK the Trolls have no reason changing the syntax of the meta-object system before a while...
I suppose the problem comes from the fact that my nodes are created in a separate thread (to avoid GUI freeze) which gets destroyed afterward (thus no event loop is running). So I added a "QHash<QAction*, const char*> slot_table;" member which is filled in the setupMenu() method with appropriate action-method name pairs. Then, after menu execution I use the following code :
Code:
if ( a && slot_table.contains(a) )
{
int idx = metaObject()->indexOfSlot(slot_table[a]);
}
Re: What's wrong with my actions???
Quote:
Originally Posted by
fullmetalcoder
I suppose the problem comes from the fact that my nodes are created in a separate thread (to avoid GUI freeze) which gets destroyed afterward (thus no event loop is running).
If the is no event loop running in that thread, queued connections won't work.
Quote:
Originally Posted by
fullmetalcoder
So I added a "
QHash<
QAction*, const char*> slot_table;" member which is filled in the setupMenu() method with appropriate action-method name pairs.
Isn't that an equivalent of adding Qt::DirectConnection to connect statements?
Re: What's wrong with my actions???
Quote:
Originally Posted by
jacek
If the is no event loop running in that thread, queued connections won't work.
Isn't that an equivalent of adding Qt::DirectConnection to connect statements?
Well, I expected my slots to be called directly but I think I now understand why they were not even if it looks strange... My nodes have been created in a given (now defunct) thread and some of their methods are called from the GUI thread. In this case created objects will be attached to the GUI thread (or am I missing something??) and it will cause Queued Connections by default which won't work properly...
Re: What's wrong with my actions???
Quote:
Originally Posted by
fullmetalcoder
My nodes have been created in a given (now defunct) thread and some of their methods are called from the GUI thread.
Maybe it will be enough if you simply move those objects to the GUI thread using QObject::moveToThread()?
Re: What's wrong with my actions???
Quote:
Originally Posted by
jacek
I thought about that already but did not find any convininent way to do it in my code... Anyway I'm done now.:D