Sending signal from static class method in Qt

19,174

Solution 1

That is not going to work, because you are creating a new Foo every time you enter that static function, and you do not connect a signal to a slot.

So, the fix would be to pass the object to that function :

class Foo
{
signals:
    emitFunction(int);
private:
    static int callback(int val, Foo &foo)
    {
        /* Called multiple times (100+) */
        foo.emitFunction(val);
    }
    void run()
    {
        callback(percentdownloaded, *this);
    }
};

Another option is to use postEvent, but I wouldn't recommend it.


Since you can not modify callback's signature, you can do it like this :

class Foo
{
signals:
    emitFunction(int);
private:
    static int callback(int val)
    {
        /* Called multiple times (100+) */
        theFoo->emitFunction(val);
    }
    static Foo *theFoo;
    void run()
    {
        callback(percentdownloaded, *this);
    }
};

but you'll have to initialize that static variable somewhere.

Solution 2

in case someone still finding the solution, here is what I did, it works in my project. 1. make your class to be a singleton 2. in static cb function , load emitFunction from the your singleton class

    static int callback(int val)
   {
   /* Called multiple times (100+) */
   MYClass::getInstance()->emitFunction(val);
   }

Solution 3

There is an elegant solution. You can emit a signal in a static member function like this:

emit (instance().newMessage(message));
Share:
19,174

Related videos on Youtube

user99545
Author by

user99545

Updated on June 04, 2022

Comments

  • user99545
    user99545 almost 2 years

    I am trying to code a static callback function that is called frequently from another static function within the same class. My callback function needs to emit a signal but for some reason it simply fails to do so. I have put it under a debugger and the slot never gets called. However when I place the code I used to emit the data in a non-static function it works. Is there a reason I cannot emit a signal from a static function? I have tried declaring a new instance of the class and calling the emit function but with no luck.

    class Foo
    {
    signals:
        emitFunction(int);
    private:
        static int callback(int val)
        {
            /* Called multiple times (100+) */
            Foo *foo = new Foo;
            foo.emitFunction(val);
        }
        void run()
        {
            callback(percentdownloaded);
        }
    };
    

    I have posted some basic code that demonstrates what I am attempting to do. I will post full code upon request.

    Edit: I am posting the full code since this is kind of an odd scenario. http://pastebin.com/6J2D2hnM

    • Lol4t0
      Lol4t0 about 12 years
      In clicked function you connected your slot to one Foo, but in callback you created another separate Foo that knows nothing about first foo. And you emit signal of this new Foo, but signals of new Foo are not connected to any slots.
    • Nobody moving away from SE
      Nobody moving away from SE
      Where do you connect the SIGNAL and the SLOT?
  • user99545
    user99545 about 12 years
    This would work, but the problem is my static callback function is being called by another function that is from the libCURL library and I cannot pass arguments to it. I am not sure how to implement your method in this case.
  • BЈовић
    BЈовић about 12 years
    @user99545 add a static variable, which is used in the callback. I'll edit the answer
  • user99545
    user99545 about 12 years
    Thanks. I ended up using your static variable and initialized it by passing the current class instance as a parameter to the thread. I used that parameter to initialize the class and it worked.
  • one
    one almost 10 years
    Thanks so much! I wasted hours on trying to get it to work, your second suggestion was great!
  • g24l
    g24l over 8 years
    nice approach and simple, it is even thread safe since signal emit is. +1
  • Majid Hojati
    Majid Hojati over 6 years
    @BЈовић I tried the second approach but it says undefined reference to `Foo ::theFoo' when I want to initialize it in contractor.
  • BЈовић
    BЈовић over 6 years
    @MajidHojati What is "contractor"? See stackoverflow.com/questions/4547660/…