Connect do not find slots under Q_OS_LINUX macro



  • I'm making an app who run both on windows and linux.
    The linux version in detail must run an external process so i've created a QProcess object and relative slots enclosed into Q_OS_LINUX.

    The problem is that the QObject::connect function cannot find the slots.
    I've prepared a fresh-new mini app to demonstrate this, who show the problem (i'm running Ubuntu 16.04 X64, qt5.5.1)

    MainWindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QProcess>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    private slots:
        #ifdef Q_OS_LINUX
        void myFinishedSlot(int);
        #endif
    private:
        Ui::MainWindow *ui;
        #ifdef Q_OS_LINUX
        QProcess *myProcess;
        #endif
    };
    
    #endif // MAINWINDOW_H
    

    MainWindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        #ifdef Q_OS_LINUX
        myProcess=new QProcess(this);
        connect(myProcess,SIGNAL(finished(int)),this,SLOT(myFinishedSlot(int)));
        myProcess->start("7za");
        #endif
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    #ifdef Q_OS_LINUX
    void MainWindow::myFinishedSlot(int retValue){
        qDebug()<<retValue;
    }
    #endif
    

    Once started, in the application output area i can see:

    QObject::connect: No such slot MainWindow::myFinishedSlot(int) in ../slot_test/mainwindow.cpp:12
    QObject::connect:  (receiver name: 'MainWindow')
    

    I cannot figure out why i get this message. Obviously, removing Q_OS_LINUX limitation make the app work but this is not the wanted solution ( it make process and slots also included into the windows binaries).

    Ivan.



  • add -DQ_OS_LINUX when you call moc

    you can achieve it adding this to the .pro file

    unix:!macx {
    QMAKE_MOC = $$QMAKE_MOC -DQ_OS_LINUX
    }
    

    as a side comment: you can use KArchive to handle 7zip (but not only 7zip) archives in a platform independent way rather than calling 7za


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Not a direct answer but since it's something private anyway, a lambda might be a better choice in your case thus avoiding the need for the macro in the header.



  • This post is deleted!


  • @VRonin said in connect do not find slots under Q_OS_LINUX macro:

    add -DQ_OS_LINUX when you call moc

    you can achieve it adding this to the .pro file

    Adding -DQ_OS_LINUX cause a redeclaration warning, but following your idea with this code in the .pro file

    !win32{
        DEFINES += MOC_OS_LINUX
    }
    

    and then in the mainwindows.h file

    #if defined(Q_OS_LINUX) || defined(MOC_OS_LINUX)
    void myFinishedSlot(int);
    #endif
    

    Works without warnings. May not be eye-friendly but as a ''''''temporary''''' solution is acceptable

    To the side comment: my goal is so basic that just by calling 7za with two parameters is all i need. Wrote that code faster than a running Bolt.

    EDIT: you wrote another piece of post while i was typing previous text. I'm now trying with your suggestion

    EDIT2: your solution do not work, i suspect QMAKE_MOC is ignored by the system since the -DQ_OS_LINUX do not appear in the parameter list when moc is called during build. Also tried to comment out 'unix:!macx' condition, but same result. Temporary i'll use my previous solution


  • Qt Champions 2016

    This is a bad way of designing an API!
    Here's what the user of your library is supposed to do for each of the OSes:

    #ifdef Q_OS_LINUX
        myobject.lunuxOnySlot();
    #else
        myobject.slotNotInLunux();
    #endif
    

    ?

    Stick to what @SGaist wrote and don't ifdef the public API, hide the private implementation details (the OS dependence) in a lambda or behind the PIMPL idiom instead.

    Kind regards.


Log in to reply
 

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