Using QLocalSocket with GUI signal readyRead is not emitted (or slot is not being called)



  • Hi all,
    I'm writing a small program to inetrcept the Power Button press on a PC running Linux.
    On Linux this could be done using the acpid daemon which is sending its events on the unix socket /var/run/acpid.socket.

    I created a small Qt program that uses QLocalSocket to connect to the acpid daemon, listen to incoming events and print them on the console. Another version of the same program (created only for debug purposes) uses a GUI to display a counter of the events intercepted from the acpid daemon (it is the same program but with a GUI).

    I'm showing some code for clarity.

    main.cpp
    @
    #ifdef NO_GUI
    // CONSOLE VERSION
    #include <QtCore/QCoreApplication>
    #include "mainconsole.h"
    #else
    // GUI VERSION
    #include <QtGui/QApplication>
    #ifdef Q_WS_QWS
    #include <QWSServer>
    #endif
    #include "mainwindow.h"
    #endif

    int main(int argc, char *argv[])
    {
    #ifdef NO_GUI
    QCoreApplication a(argc, argv);
    // CONSOLE VERSION
    MainConsole w;
    #else
    // GUI VERSION
    QApplication a(argc, argv);
    MainWindow w;
    #ifdef Q_WS_QWS
    QWSServer::setCursorVisible( false );
    w.showFullScreen();
    #else
    w.show();
    #endif
    #endif

    return a.exec&#40;&#41;;
    

    }
    @

    mainconsole.cpp
    @
    #include "mainconsole.h"
    #include <QtNetwork/QLocalSocket>

    #ifdef _WIN32
    #define SOCKET_NAME "\\.\pipe\foo"
    #endif

    #ifdef linux
    #define SOCKET_NAME "/var/run/acpid.socket"
    #endif

    MainConsole::MainConsole(QObject *parent) :
    QObject(parent)
    {
    socket = new QLocalSocket();
    connect(socket, SIGNAL(readyRead()), this, SLOT(onSocketDataReady()));
    connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(onSocketError(QLocalSocket::LocalSocketError)));

    socket->connectToServer(SOCKET_NAME, QIODevice::ReadOnly);
    if (socket->waitForConnected(1000))
        qDebug("Connected!");
    

    }

    void MainConsole::onSocketDataReady()
    {
    QDataStream in(socket);
    in.setVersion(QDataStream::Qt_4_0);
    QString data(socket->readAll());
    qDebug() << "Data received: " << data;
    if(data.contains(QString("button/power")))
    qDebug("PowerButton pressed detected!\n");
    }

    void MainConsole::onSocketError(QLocalSocket::LocalSocketError error)
    {
    qDebug() << "Socket Error: " << error;
    }
    @

    mainwindow.cpp
    @
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QDebug>

    #ifdef _WIN32
    #define SOCKET_NAME "\\.\pipe\foo"
    #endif

    #ifdef linux
    #define SOCKET_NAME "/var/run/acpid.socket"
    #endif

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    count = 0;
    socket = new QLocalSocket();
    
    connect(socket, SIGNAL(readyRead()), this, SLOT(onSocketDataReady()));
    connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(onSocketError(QLocalSocket::LocalSocketError)));
    
    socket->connectToServer(SOCKET_NAME, QIODevice::ReadOnly);
    if (socket->waitForConnected(1000))
         qDebug("Connected!");
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::onSocketDataReady()
    {
    QDataStream in(socket);
    in.setVersion(QDataStream::Qt_4_0);
    QString data(socket->readAll());
    qDebug() << "Data received: " << data;
    if(data.contains(QString("button/power")))
    {
    count++;
    ui->labelCount->setText(QString::number(count));
    qDebug("PowerButton pressed detected!\n");
    }
    }

    void MainWindow::onSocketError(QLocalSocket::LocalSocketError error)
    {
    qDebug() << "Socket Error: " << error;
    }
    @

    All the code compiles fine, both the console version and the gui version, but when I run the application, the console version works as expected and prints out the strings received from the socket. The gui version instead, never enters in the onSocketDataReady() slot and never prints out nothing on the qDebug() nor update the label in the UI.

    I can't understand where's the difference in the signal-slot calling with and without the UI, in this program.

    Thanks for any help/suggestions.
    Samuele.



  • can you post header files for mainwindow and mainconsole please?



  • Yes, sure.

    mainconsole.h
    @
    #ifndef MAINCONSOLE_H
    #define MAINCONSOLE_H

    #include <QObject>
    #include <QtNetwork/QLocalSocket>

    class MainConsole : public QObject
    {
    Q_OBJECT
    public:
    explicit MainConsole(QObject *parent = 0);
    ~MainConsole();

    void close();
    

    private:
    QLocalSocket *socket;

    signals:

    public slots:
    void onSocketDataReady();
    void onSocketError(QLocalSocket::LocalSocketError);
    };

    #endif // MAINCONSOLE_H
    @

    mainwindow.h
    @
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QtNetwork/QLocalSocket>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    int count;
    QLocalSocket *socket;

    private:
    Ui::MainWindow *ui;

    public slots:
    void onSocketDataReady();
    void onSocketError(QLocalSocket::LocalSocketError);
    };

    #endif // MAINWINDOW_H
    @

    And this is the .pro file:
    TestQtAcpi.pro
    @
    #-------------------------------------------------

    Project created by QtCreator 2013-01-14T17:13:28

    #-------------------------------------------------

    CONFIG += gui

    QT += core network
    TARGET = TestQtAcpi

    nogui {
    CONFIG += console
    CONFIG -= app_bundle
    DEFINES += NO_GUI
    SOURCES += mainconsole.cpp
    HEADERS += mainconsole.h
    } else {
    QT += gui
    SOURCES += mainwindow.cpp
    HEADERS += mainwindow.h
    FORMS += mainwindow.ui
    }

    TEMPLATE = app

    SOURCES += main.cpp
    @



  • you might want to give ownership of the local socket

    @
    socket = new QLocalSocket(this);
    @



  • Sorry for the late reply.
    I have tested the software also using:
    @socket = new QLocalSocket(this);@

    but nothing has changed.
    The NON-GUI version intercept correctly the signals, but the GUI version does not intercept any signal, so the slot is never being called.
    On the Linux board where I test this program, I run the application with this command:
    @# ./TestQtAcpi -qws@

    because it runs Qt in framebuffer (not inside a desktop environment). Do you think that this could interfere with the signal-slot messaging?



  • Anyway, this is not a problem caused by running the application on the framebuffer.
    I've made a test also on a normal Qt installation but it has the same behaviour, the GUI version does not receive any readyRead signal from the QLocalSocket and so the slot is never being called.



  • Hi samueleforconi!
    I have tested your code on my system (KUbuntu 12.04.1 LTS 64 bit, Qt 4.8.4) and all works fine.
    Please, tell your options for qmake which you use for build gui/nongui version.



  • I have tested on Ubuntu Desktop and it works (both the GUI and the console version).
    Testing on an embedded x86 PC that runs Ubuntu Server 12.04 and Qt in framebuffer mode tha GUI version won't work...

    I'll explain what I'm seeing as output on the console:
    @
    Connected!
    Data received: "button/power PWRF 00000080 00000031
    button/power PWRF 00000080 00000032
    button/power PWRF 00000080 00000033
    "
    PowerButton pressed detected!

    Data received: "button/power PWRF 00000080 00000034
    button/power PWRF 00000080 00000035
    button/power PWRF 00000080 00000036
    button/power PWRF 00000080 00000037
    "
    PowerButton pressed detected!

    Data received: "button/power PWRF 00000080 00000038
    button/power PWRF 00000080 00000039
    button/power PWRF 00000080 0000003a
    "
    PowerButton pressed detected!

    Data received: "button/power PWRF 00000080 0000003b
    "
    PowerButton pressed detected!
    @

    As you can see, sometimes the slot gets executed, but it's not deterministic... sometimes I need to press the button 2, 3 or 4 times before I can see the debug output on the console... and you can count how many times I have pressed the button watching at the "Data received:" output.

    I can't understand this behaviour...


Log in to reply
 

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