Qt-interest Archive, September 2002
Signals in static object?
Message 1 in thread
Hi
I am developing an application in which I need the items inside
my QListView to be able to emit a signal. I could derive a new
item class from QListViewItem in which I implement a signal and
connect it to the receiver slot. But the item doesn't know the
receiver and using a global variable to hold the pointer to the
receiver is clumsy.
Instead I decided to derive from QListViewItem and embed a static
object in the item class. The static object is known to all objects
of my derived item class, as well as to the receiver. It is derived
from QObject so it should be able to emit a signal. Here is a scaled
down version:
class CommonListViewItemSignalSlotHandler: public QObject
{
Q_OBJECT;
public:
CommonListViewItemSignalSlotHandler(QObject * parent=0, const char *
name=0);
void Busy(boolean busy)
{
emit(this, SIGNAL(Signal_Busy(ON)));
}
signals:
void Signal_Busy(boolean)
};
class PopUpListViewItem: public QListViewItem
{
public:
PopUpListViewItem (QListView* parent, etc etc);
static CommonListViewItemSignalSlotHandler SsHdl;
etc etc....
};
CommonListViewItemSignalSlotHandler PopUpListViewItem::SsHdl(0, "SsHdl");
I have deliberately removed unrelated stuff so please don't tell me that
it can't compile :-)
In the constructor of the QMainWindow I connect the signal:
ASSERT(connect(&PopUpListViewItem::SsHdl, SIGNAL(void Signal_Busy(boolean)),
this, SLOT(Slot_SetBusy(boolean))));
It compiles OK but it doesn't work at all. The slot never receives the
signal. Instead I get these debug messages:
QObject::connect: No such signal CommonListViewItemSignalSlotHandler::void
Signal_Busy(boolean)
QObject::connect: (sender name: 'SsHdl')
QObject::connect: (receiver name: 'PopUp')
ASSERT: "connect(&PopUpListViewItem::SsHdl, SIGNAL(void
Signal_Busy(boolean)), this, SLOT(Slot_SetBusy(boolean)))" in
D:\Cpp\Appl\PopUp\PopUp.cpp (230)
I think my main problem is that I do not understand the signal/slot
mechanism well enough. Is this method at all possible, and if it isn't,
why not? I'm sure there must be a simple and elegant solution this quite
common problem. If anybody knows what it is please tell me.
TIA
regards
Morten
Message 2 in thread
On Thursday 19 September 2002 04:59, Morten Højberg Pedersen wrote:
> Hi
>
> I am developing an application in which I need the items inside
> my QListView to be able to emit a signal. I could derive a new
> item class from QListViewItem in which I implement a signal and
> connect it to the receiver slot. But the item doesn't know the
> receiver and using a global variable to hold the pointer to the
> receiver is clumsy.
>
Why not use a Singleton class? For exanple...
Your header file would look something like this:
class MyClass
{
public
static MyClass* theInstance();
static void destroyTheInstance();
....
private:
MyClass(); // Make constructor and destructor private
~MyClass();
static MyClass* s_instance;
};
And your .cpp would look something link this:
MyClass* MyClass::s_instance = NULL;
MyClass* MyClass::theInstance()
{
// Create the instance the first time called, otherwise
// return the already existing instance!
if (s_instance)
{
s_instance = new MyClass();
}
return s_intance;
}
void MyClass::destroyTheInstance()
{
delete s_instance;
s_instance = NULL;
}
....
By making the constructor private and adding "theInstance" member function
you gurantee that there can be only one instance at a time (just like a
static class). Other classes can also access the Instance safely by usinng
the "theInstance" member function, once accessed it can almost be treated
just like any other class. The other advantage of something like this is
that you avoid an ugly global variable.
Bryan
Message 3 in thread
Hi again
Some kind people has pinpointed half of the problem: the signal part of
the connection should not include the 'void' return type! Nor should the
line be wrapped in an ASSERT, but that is another matter!
Removing the 'void' also removes the debug messages. But still the signal
never reaches the slot. So something is wrong afterall.
Does anybody out there know of a way to debug signals/slots in cases like
this?
Thanks.
best regards
Morten
-----Original Message-----
From: Morten Højberg Pedersen
Sent: Thursday, September 19, 2002 1:59 PM
To: 'qt-interest@trolltech.com'
Subject: Signals in static object?
Hi
I am developing an application in which I need the items inside
my QListView to be able to emit a signal. I could derive a new
item class from QListViewItem in which I implement a signal and
connect it to the receiver slot. But the item doesn't know the
receiver and using a global variable to hold the pointer to the
receiver is clumsy.
Instead I decided to derive from QListViewItem and embed a static
object in the item class. The static object is known to all objects
of my derived item class, as well as to the receiver. It is derived
from QObject so it should be able to emit a signal. Here is a scaled
down version:
class CommonListViewItemSignalSlotHandler: public QObject
{
Q_OBJECT;
public:
CommonListViewItemSignalSlotHandler(QObject * parent=0, const char *
name=0);
void Busy(boolean busy)
{
emit(this, SIGNAL(Signal_Busy(ON)));
}
signals:
void Signal_Busy(boolean)
};
class PopUpListViewItem: public QListViewItem
{
public:
PopUpListViewItem (QListView* parent, etc etc);
static CommonListViewItemSignalSlotHandler SsHdl;
etc etc....
};
CommonListViewItemSignalSlotHandler PopUpListViewItem::SsHdl(0, "SsHdl");
I have deliberately removed unrelated stuff so please don't tell me that
it can't compile :-)
In the constructor of the QMainWindow I connect the signal:
ASSERT(connect(&PopUpListViewItem::SsHdl, SIGNAL(void Signal_Busy(boolean)),
this, SLOT(Slot_SetBusy(boolean))));
It compiles OK but it doesn't work at all. The slot never receives the
signal. Instead I get these debug messages:
QObject::connect: No such signal CommonListViewItemSignalSlotHandler::void
Signal_Busy(boolean)
QObject::connect: (sender name: 'SsHdl')
QObject::connect: (receiver name: 'PopUp')
ASSERT: "connect(&PopUpListViewItem::SsHdl, SIGNAL(void
Signal_Busy(boolean)), this, SLOT(Slot_SetBusy(boolean)))" in
D:\Cpp\Appl\PopUp\PopUp.cpp (230)
I think my main problem is that I do not understand the signal/slot
mechanism well enough. Is this method at all possible, and if it isn't,
why not? I'm sure there must be a simple and elegant solution this quite
common problem. If anybody knows what it is please tell me.
TIA
regards
Morten
--
[ signature omitted ]
Message 4 in thread
Hi everyone,
One thing I would suggest, (and this may be obvious,) have you re-ran
through the moc compiler?
This would happen to me a lot, where I would have a project and add 1
signal. If you don't re-run the moc, the code compiles fine. The signal
fires, but doesn't "know" to call the correct function, since the slot lists
didn't get re-freshed.
I'm probably totally wrong but...
--
[ signature omitted ]
Message 5 in thread
Hi again.
I have discovered the problem (last night :-). It was caused by this
line
emit(this, SIGNAL(Signal_Busy(ON)));
which should ofcourse read
emit Signal_Busy(ON);
A truly stupid error! And somehow the preprocessor managed to reduce this to
an empty line when expanding the emit and SIGNAL macros. I find it worrying
that
I can make such syntactical blunders without any warnings from the
preprocessor
or the compiler. Guess that is minor drawback when using the signal/slot
mechanism.
Thanks to all that replyed to my request. Allthough they did not spot the
bug
I did certainly learn a few things from their replies.
regards
Morten