PDA

View Full Version : Events



T0bi4s
15th November 2009, 17:19
Hi guys,

got some question concerning events in qt. at first i used the signal slot princip like this one :

connect(b_loadDB, SIGNAL(clicked()),in,SLOT(loadDB()));
to connect an event with a method.

but i want it to be like actionlisteners in java, i read something about events:confused:, but i can't help myself with it. anyway that's my question, is there a way to check events and do then methods and get return values, like in java (cause i think, it's a pretty easy principle)

i hope somebody can help me
thx
tobi

squidge
15th November 2009, 18:04
Sure, you can:



int QEvent::registerEventType ( int hint = -1 )


and then:



void QCoreApplication::postEvent ( QObject * receiver, QEvent * event )
bool QCoreApplication::sendEvent ( QObject * receiver, QEvent * event )


Making sure to override the event() method for each widget to process those events.

A much easier way would be to use signals and slots though, as you would have to subclass QEvent for each type of data you want to send.

T0bi4s
15th November 2009, 18:44
i'm not sure if i understood what i wanted to tell me.


int QEvent::registerEventType ( int hint = -1 )

why integer at the beging? or better, what does this line do? i thought of something like create an event like "clicked" or something like that.

and what's the
int hint = -1 ? i don't get this one


what's the differenc between postEvent and sendEvent? and from where is the returnvalue or what does the returnvalue mean?:

void QCoreApplication::postEvent ( QObject * receiver, QEvent * event )

i know some newbie question
but thx for your quick answer, hope you're still there to help me again
tobi

squidge
15th November 2009, 19:49
All event types have a number, hence the returning of an integer. User events are numbers >= 1000. Its upto you to decide what each number means. The hint is if you want a specific number. -1 means you want the next available number.

postEvent returns immediately (before the event has been processed by the receiver)
sendEvent returns when the event has been processed, and returns the boolean return value

The event handler returns true if the event was recognised, false otherwise, and you get this value from sendEvent. postEvent can't return this as the event will not have been processed by the time the function returns.

T0bi4s
15th November 2009, 22:18
ok i got so far

but still a question if i can specify the events and mark each event with a number, how do i specify the event?


int QEvent::registerEventType ( int hint = -1 )

should create an event with the first avilable number (cause of the hint = -1) and how i know which it is? like clicked i mean

or do i have to use it like


int eventnumber_clicked;

QEvent e_clicked;
eventnumber_clicked = e_clicked::registerEventType (int hint =-1);


it was just a propose, i don't know. anway how do i link the event with an object (like a button) and


void QCoreApplication::postEvent ( QObject * receiver, QEvent * event )
what is meant here with receiver? is it a e.g. a button und meant to link event with widget or what?
and what will be done when event occurs? or do i just know that it's done and check it with an "if"?

thx 4 help
tobi

squidge
16th November 2009, 08:15
for each event, you have to subclass QEvent, eg:



class myEvent : public QEvent
{
// data structure for event
};

myEvent *event;

myevent_type = registerEventType();
event = new myEvent(myevent_type);


and then override event method:



bool event (QEvent *event)
{
if (event->type == myevent_type)
{
/* foo */
}
}


'receiver' is who should receive the event. So far example, to send the event to yourself, you would put 'this', and to send to a button, you would use maybe 'mybutton', which is perhaps of type QWidget.

T0bi4s
16th November 2009, 12:27
man you're great!!!:)

just one more thing, what you mean with datastructure of the event? is that something like clicked() or what is meant with that?

thx tobi

squidge
16th November 2009, 13:04
It means whatever data you want to send with the event. You might want to send a flag (eg. Pressed or Released) or perhaps some text. Your event handler can then access this information and do what it likes with it.

So instead of having, for example, MousePressedEvent and MouseReleasedEvent, you would have MouseEvent, and in there you would have a variable called "Pressed".

wysota
16th November 2009, 13:19
If you want to get a return value then most likely you know the object you expect to return such value. In that case you can call its method directly without using events or signals. Using events in your situation doesn't make that much sense (as you need to know where to send the event to), it's easier to obtain the same effect using signals anyway...

Coises
16th November 2009, 17:30
is there a way to check events and do then methods and get return values

I think a combination of QObject::sender() and QObject::qobject_cast would allow you to do what you want, though I haven’t had occasion to try it yet. For example:


FancyButton* fb = qobject_cast<FancyButton*>(sender());
if (fb) {
code here can use fb->any_accessible_member_or_method
// (non-public members/methods only if FancyButton declares this class a friend)
// If called (not signaled), or if signaled by something that is not a FancyButton
// or a sub-class of FancyButton, fb will be 0 and the if block won't be entered.
}


If you control the code for the signaling objects as well, a simpler and safer way would be to change the signal and slot to take the this pointer of the signaling object as an argument.

T0bi4s
25th November 2009, 14:25
hi again,

long time ago i last answered. and again this way of sender and cast. how does it work? i tried to open a qdialog with a button click but it didn't work lik i did:




QDialog dia_job;
QDialog dia_package;

Ui::d_job uij;
uij.setupUi(&dia_job);

Ui::d_package uip;
uip.setupUi(&dia_package);


uij.tb_set_package = qobject_cast<QToolButton*>(dia_package.show());

if(uij.tb_set_package){
qDebug("clicked");
dia_package.show();
}


qcreator says incalid use of void expression, i can guess why, but what should it look like that it works?

or found another thing



void PaintArea::mouseMoveEvent(QMouseEvent *event)
{
if ((event->buttons() & Qt::LeftButton) && lastPos != QPoint(-1, -1)) {
if (brushInterface) {
QPainter painter(&theImage);
setupPainter(painter);
const QRect rect = brushInterface->mouseMove(brush, painter, lastPos,
event->pos());
update(rect);
}

lastPos = event->pos();
}
}
this is just an example i found, but how can i link an event with an button? i tried

void mouseclick(QMouseEvent *e){
if(e){
}
}
in the headerfile of my ui file but actually i can't use the dot-extension for the event e, why? anyone got an idea?

thx
tobi

squidge
25th November 2009, 16:12
void mouseclick(QMouseEvent *e){
if(e){
}
}
in the headerfile of my ui file but actually i can't use the dot-extension for the event e, why? anyone got an idea?
dot-extension? If you mean you can't use 'e.' then of course you can't. 'e' is a pointer, not a reference.

I've no idea what else your trying to do with the rest of the code.

I said at the beginning of the thread, you should be using signals and slots. Thats how you handle events from objects.

T0bi4s
25th November 2009, 16:24
i see your point, anyway got the problem that i can't use the connect function in the main part of my project, it says that connect is not declared.

can't i use it in the main.cpp? --> if so, do i have to create a e.g. main working class?

edit:
by the way, what's the diffrence between an signal and a virtual signal?

squidge
25th November 2009, 17:46
You can use connect() from any class that derives from QObject, so make sure your class does.

I've no idea what a virtual signal is. Virtual slot, yes, but not signal.

T0bi4s
25th November 2009, 18:05
ok my bad i meant slots, just wrote signals :o

thx for the connect answer()

squidge
25th November 2009, 20:53
Ok, a virtual slot is one where when you override the name in your own class that inherits the class with a virtual slot, your slot will be called rather than the base class even if the pointer type references the base rather than your class type.

Wow, that came out like mud. Lets try again: If you have class 'a' that has virtual slot 'vslot' and you subclass that class and call it 'b'. You then create a variable "a *myclassInstance" and call vslot via myclassInstance->vslot(). Even though you don't reference class "b", class b's 'vslot' will be called rather than base call a's. If it wasn't virtual, it would call class a's vslot instead, unless myclassInstance definition was "b *myclassInstance".

Hopefully thats more clear.

T0bi4s
25th November 2009, 22:09
thx, was clear enough :)