Mixing pthreads and main GUI thread - Can pthread function emit a signal



  • Hello

    My -QT- Qt desktop application is a Server which is listening to connections from clients.
    The main GUI runs in the main thread. When a client starts, it is accepted on a new thread which is a pthread (say t1)

    The need is to intimate the GUI thread of data received. I get a QPixMap error if i try to draw anything on the GUI using t1.
    Hence I need to intimate the main thread through a slot and signal. The functionality after accepting the client is running in a new global function according to pthread design. Do I need to move this to a new class or is there any other way

    Thanks in advance



  • Any GUI related operations can only be done in the GUI thread (with some minor exceptions).

    The easiest solution might be migrating your pthreads code to QThreads, in which case you can use ordinary signals and slots to communicate among threads.



  • Hi

    I have made the code changes it looks like this :

    @
    class SANServer : public QThread
    {

    Q_OBJECT
    

    .........
    signals:
    void EmitServerConnected();
    };
    @

    In the constructor of the mainwindow,

    @
    connect(iSANServer, SIGNAL(EmitServerConnected()), this, SLOT(NotifyServerConnected()));
    @

    in the class of mainwindow

    @
    private slots:
    void NotifyServerConnected();
    @

    In the mainwindow.cpp file

    @
    void MainWindow::NotifyServerConnected()
    {
    }
    @

    In one of the functions of the mainwindow

    @
    iSANServer = new SANServer(port_1, num_1);
    iSANServer->start();
    @

    Constructor of iSANserver

    @
    SANServer::SANServer(int aPort, int aMaxClients)//, ServerObserver &aObserver) : iObserver(aObserver)
    {
    iPort = aPort;
    iMaxClients = aMaxClients;
    @

    However Im getting the following errors :

    @
    /home/sudhix/QtProjects/SANServer-build-desktop/../SANServer/SANServer.cpp:3: error: undefined reference to `vtable for SANServer'
    @
    Im not sure why the vtable error is comming for the SANServer.

    @
    /home/sudhix/QtProjects/SANServer-build-desktop/../SANServer/SANServer.cpp:95: error: undefined reference to `SANServer::EmitServerConnected()'
    @
    I havent defined the function for emiting the signal. How may I do this?? or is there a standard signal i can use?

    Thanks



  • Re-run qmake, this will usually solve your problem (and most of the v-table like errors you may encounter).

    However, the NotifyServerConnected -signal- slot should be public, not private.



  • [quote author="Lukas Geyer" date="1309332189"]However, the NotifyServerConnected signal should be public, not private.[/quote]NotifyServerConnected is a slot. It is irrelevant whether the access is private, protected or public, because the meta object can always invoke it. The signal cannot have access specifiers (it is always protected).

    To emit signals, place @emit EmitServerConnected();@ somewhere in the code, where you think it makes sense to emit the signal.

    Incidentally, I think EmitServerConnected() and NotifyServerConnected() are poorly chosen names. EmitServerConnected() should probably be called serverConnected() or connected(). NotifyServerConnected() should be named after what it does, not what you make it react to. It is in essence a normal function, so it is best to choose a name that fits with its behavior.



  • [quote author="Franzk" date="1309339068"] It is irrelevant whether the access is private, protected or public, because the meta object can always invoke it. The signal cannot have access specifiers (it is always protected).[/quote]

    That's true. But this is a question of interface design. Public slots can and should be invoked from other classes, whereas private slots should not - even if the system -supports it- lacks support for encapsulation.

    [quote author="Franzk" date="1309339068"]NotifyServerConnected is a slot.[/quote]I meant slot, didn't I write it? ;-)



  • Hello All

    Thanks for your help. The code has started working :)

    Changes made

    @
    public:
    void run(void);

    changed to

    protected:
    virtual run(void);
    @

    Slots are made public

    1. Most importantly, deleted all object files, did a clean, restarted QTcreator and it compiled.
      Maybe a combination of all these helped it to work :)


  • [quote author="yannifan" date="1309330871"]

    @
    /home/sudhix/QtProjects/SANServer-build-desktop/../SANServer/SANServer.cpp:3: error: undefined reference to `vtable for SANServer'
    @
    Im not sure why the vtable error is comming for the SANServer.
    [/quote]

    Running qmake would solve this, it usually occurs because of moc skipping the class.



  • [quote author="Lukas Geyer" date="1309332189"]
    However, the NotifyServerConnected -signal- slot should be public, not private.[/quote]

    You can connect signals to private slots.



  • [quote author="kkrzewniak" date="1309352010"]You can connect signals to private slots.[/quote]
    [quote author="Lukas Geyer" date="1309340405"]That's true. But this is a question of interface design. Public slots can and should be invoked from other classes, whereas private slots should not - even if the system -supports it- lacks support for encapsulation.[/quote]



  • Yes I'm aware of your view that one should not connect foreign signals to private slots, but you have not mentioned it in your original post concerning making the slot public. This may lead to a false assumptions that such connections are impossible.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.