×

Discussion Board

Results 1 to 4 of 4
  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    6

    Signals_and_Slots_on_QThread_wit_sired_class

    goodday everyone
    I have a problem with signals and slots when using a shared file called 'settings'.
    I'm unable to emit a signal from settings if it's been been called from a sub thread.
    To demonstrate problem I wrote this little program:

    CODE

    Signals_and_Slots_on_QThread_wit_sired_class.PRO
    Code:
    QT       += core gui
    
    TARGET = Signals_and_Slots_on_QThread_wit_sired_class
    TEMPLATE = app
    
    SOURCES += main.cpp\
            widget.cpp \
        thread.cpp \
        settings.cpp
    
    HEADERS  += widget.h \
        thread.h \
        settings.h
    main.cpp
    Code:
    #include <QtGui/QApplication>
    #include "widget.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
    
        return a.exec();
    }
    widget.h
    Code:
    #ifndef WIDGET_H
    #define WIDGET_H
    #include "settings.h"
    #include "thread.h"
    #include <QtGui/QWidget>
    #include <QLineEdit>
    #include <QTextBrowser>
    #include <QGridLayout>
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
    
    public slots:
        void print(QString,int,int,int);//text, red, green, blue
        void print_append(QString,int,int,int);//text, red, green, blue
    
    private:
        Thread thread;
        settings Settings;
        QLineEdit *lineEdit;
        QTextBrowser *textBrowser_info;
    
    private slots:
        void readSettings();
    };
    #endif // WIDGET_H
    widget.cpp
    Code:
    #include "widget.h"
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        lineEdit = new QLineEdit;
        textBrowser_info = new QTextBrowser;
        QGridLayout *layout = new QGridLayout;
        layout->addWidget(lineEdit, 0, 0);
        layout->addWidget(textBrowser_info, 1, 0);
        setLayout(layout);
        /* Settings */
            connect(&Settings, SIGNAL(info(QString,int,int,int)),
                    this, SLOT(print(QString,int,int,int)),
                    Qt::AutoConnection);
            connect(&Settings, SIGNAL(info_append(QString,int,int,int)),
                    this, SLOT(print_append(QString,int,int,int)),
                    Qt::AutoConnection);
        /* thread */
            connect(&thread, SIGNAL(info(QString,int,int,int)),
                    this, SLOT(print(QString,int,int,int)),
                    Qt::AutoConnection);
            connect(&thread, SIGNAL(info_append(QString,int,int,int)),
                    this, SLOT(print_append(QString,int,int,int)),
                    Qt::AutoConnection);
            /* einde connect */
                        print("test start",100, 100, 100);
    
                        readSettings();
                        print("test done",100, 100, 100);
                        thread.start_uitlezen();
    }
    
    Widget::~Widget() {}
    
    void Widget::print(QString temp,int red,int green,int blue)
    {
        textBrowser_info->setTextColor(QColor(red, green, blue, 255));
        textBrowser_info->append(temp);
    }
    
    void Widget::print_append(QString temp,int red,int green,int blue)
    {
        textBrowser_info->setTextColor(QColor(red, green, blue, 255));
        textBrowser_info->insertPlainText(temp);
    }
    
    void Widget::readSettings() {
        lineEdit->setText(Settings.dir_uitlezen());
    }
    settings.h
    Code:
    #ifndef SETTINGS_H
    #define SETTINGS_H
    
    #include <QObject>
    #include <QSettings>
    const QString file="settings.ini";
    
    class settings : public QObject
    {
        Q_OBJECT
    public:
        explicit settings(QObject *parent = 0);
        QString readSettings(QString beginGroup, QString value, QString var);
    
        // readSettings
        QString dir_uitlezen();
    
    signals:
        void info(QString,int,int,int);//text, red, green, blue
        void info_append(QString,int,int,int);//text, red, green, blue
    };
    
    #endif // SETTINGS_H
    settings.cpp
    Code:
    #include "settings.h"
    settings::settings(QObject *parent) :
        QObject(parent)
    {}
    
    QString settings::readSettings(QString beginGroup, QString value, QString var)
    {
        QSettings settings(file,QSettings::IniFormat);
        QString temp;
        settings.beginGroup(beginGroup);
        temp=settings.value(value,var).toString();
        settings.endGroup();
        emit info("-settings R- ["+beginGroup+"] "+value+" ="+temp,0,100,0);
        return temp;
    }
    
    QString settings::dir_uitlezen()
    {
    #ifdef Q_OS_LINUX
        return readSettings("mapen_linux","dir_uitlezen","/home/user/Documenten/Uitlezingen/");
    #endif
    #ifdef Q_WS_WIN
    /* #elif Q_WS_WIN  "error" */
        return readSettings("mapen_windows","dir_uitlezen","C:/Documents/Uitlezingen");
    #endif
    }
    thread.h
    Code:
    #ifndef THREAD_H
    #define THREAD_H
    
    #include <QObject>
    #include <QThread>
    #include "settings.h"
    
    class Thread : public QThread
    {
        Q_OBJECT
    public:
        explicit Thread(QThread *parent = 0);
        ~Thread();
    
    protected:
        void run();
    
    signals:
        void info(QString,int,int,int);//text, red, green, blue
        void info_append(QString,int,int,int);//text, red, green, blue
    
    public slots:
        void start_uitlezen();
    
    private:
        settings Settings;
        QString dir_uitlezen;
        QString out_file;
        void readSettings();
    };
    #endif // THREAD_H
    thread.cpp
    Code:
    #include "thread.h"
    
    Thread::Thread(QThread *parent) :
        QThread(parent)
    {
        moveToThread(this);
    }
    
    Thread::~Thread()
    {
        wait();
    }
    
    void Thread::run()
    {
        exec();
    }
    
    /* => settings.h */
    void Thread::readSettings()
    {
        dir_uitlezen=Settings.dir_uitlezen();
    }
    
    void Thread::start_uitlezen()
    {
        emit info("start dir_uitlezen",0,0,100);
        readSettings();
        emit info("waarom geen '-settings R-' getoond?",255,0,0);
        emit info("done dir_uitlezen",0,0,100);
        this->exit(0);
    }
    the first time it calls settings it displays settings R and a folder.
    the second time it does not display this.
    this has been called from what I believe the thread while the same thread is able to broadcast text.
    Why is this? Did I forget something?

    sincerely
    BACKER
    Last edited by BACKER; 2011-10-06 at 17:23. Reason: /* #elif Q_WS_WIN "error" */

  2. #2
    Super Contributor
    Join Date
    Mar 2009
    Posts
    1,024

    Re: Signals_and_Slots_on_QThread_wit_sired_class

    I'm unable to emit a signal from settings if it's been been called from a sub thread.
    I think signal is emitted by settings in the thread, but you are not listening for it!

  3. #3
    Registered User
    Join Date
    Sep 2011
    Posts
    6

    Re: Signals_and_Slots_on_QThread_wit_sired_class

    yes, in debug its clearly visible,
    but
    Code:
            connect(&Settings, SIGNAL(info(QString,int,int,int)),
                    this, SLOT(print(QString,int,int,int)),
                    Qt::AutoConnection);
    not listening
    and
    Code:
    connect(&thread, SIGNAL(info(QString,int,int,int)),
                    this, SLOT(print(QString,int,int,int)),
                    Qt::AutoConnection);
    not listening

    @doc.qt.nokia.com
    A class which emits a signal neither knows nor cares which slots receive the signal.
    Signal OK
    Slot OK
    Meta-Object problem?

    I forget what?

    sincerely
    BACKER

  4. #4
    Registered User
    Join Date
    Sep 2011
    Posts
    6

    Re: Signals_and_Slots_on_QThread_wit_sired_class

    fix add => Qt::QueuedConnection

    Signals_and_Slots_on_QThread_wit_sired_class.PRO
    Code:
    QT       += core gui
    
    TARGET = Signals_and_Slots_on_QThread_wit_sired_class
    TEMPLATE = app
    
    SOURCES += main.cpp\
            widget.cpp \
        thread.cpp \
        settings.cpp
    
    HEADERS  += widget.h \
        thread.h \
        settings.h
    main.cpp
    Code:
    #include <QtGui/QApplication>
    #include "widget.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
    
        return a.exec();
    }
    widget.h
    Code:
    #ifndef WIDGET_H
    #define WIDGET_H
    #include "settings.h"
    #include "thread.h"
    #include <QtGui/QWidget>
    #include <QLineEdit>
    #include <QTextBrowser>
    #include <QGridLayout>
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
    
    public slots:
        void print(QString,int,int,int);//text, red, green, blue
        void print_append(QString,int,int,int);//text, red, green, blue
    
    private:
        Thread thread;
        settings Settings;
        QLineEdit *lineEdit;
        QTextBrowser *textBrowser_info;
    
    private slots:
        void readSettings();
    };
    #endif // WIDGET_H
    widget.cpp
    Code:
    #include "widget.h"
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        lineEdit = new QLineEdit;
        textBrowser_info = new QTextBrowser;
        QGridLayout *layout = new QGridLayout;
        layout->addWidget(lineEdit, 0, 0);
        layout->addWidget(textBrowser_info, 1, 0);
        setLayout(layout);
        /* Settings */
        connect(&Settings, SIGNAL(info(QString,int,int,int)),
                this, SLOT(print(QString,int,int,int)),
                Qt::AutoConnection);
        connect(&Settings, SIGNAL(info_append(QString,int,int,int)),
                this, SLOT(print_append(QString,int,int,int)),
                Qt::AutoConnection);
    
        /*-!! fix add => Qt::QueuedConnection <= !!-*/
        connect(&Settings, SIGNAL(info(QString,int,int,int)),
                this, SLOT(print(QString,int,int,int)),
                Qt::QueuedConnection);
        connect(&Settings, SIGNAL(info_append(QString,int,int,int)),
                this, SLOT(print_append(QString,int,int,int)),
                Qt::QueuedConnection);
        /*-!! end fix !!-*/
    
        /* thread */
            connect(&thread, SIGNAL(info(QString,int,int,int)),
                    this, SLOT(print(QString,int,int,int)),
                    Qt::AutoConnection);
            connect(&thread, SIGNAL(info_append(QString,int,int,int)),
                    this, SLOT(print_append(QString,int,int,int)),
                    Qt::AutoConnection);
            /* einde connect */
                        print("test start",100, 100, 100);
    
                        readSettings();
                        print("test done",100, 100, 100);
    
                        thread.moveToThread(&thread);
                        thread.start();
                        thread.start_uitlezen();
    }
    
    Widget::~Widget() {
        thread.quit();
    }
    
    void Widget::print(QString temp,int red,int green,int blue)
    {
        textBrowser_info->setTextColor(QColor(red, green, blue, 255));
        textBrowser_info->append(temp);
    }
    
    void Widget::print_append(QString temp,int red,int green,int blue)
    {
        textBrowser_info->setTextColor(QColor(red, green, blue, 255));
        textBrowser_info->insertPlainText(temp);
    }
    
    void Widget::readSettings() {
        lineEdit->setText(Settings.dir_uitlezen());
    }
    settings.h
    Code:
    #ifndef SETTINGS_H
    #define SETTINGS_H
    
    #include <QObject>
    #include <QSettings>
    const QString file="settings.ini";
    
    class settings : public QObject
    {
        Q_OBJECT
    public:
        explicit settings(QObject *parent = 0);
        QString readSettings(QString beginGroup, QString value, QString var);
    
        // readSettings
        QString dir_uitlezen();
    
    signals:
        void info(QString,int,int,int);//text, red, green, blue
        void info_append(QString,int,int,int);//text, red, green, blue
    };
    
    #endif // SETTINGS_H
    settings.cpp
    Code:
    #include "settings.h"
    settings::settings(QObject *parent) :
        QObject(parent)
    {}
    
    QString settings::readSettings(QString beginGroup, QString value, QString var)
    {
        QSettings settings(file,QSettings::IniFormat);
        QString temp;
        settings.beginGroup(beginGroup);
        temp=settings.value(value,var).toString();
        settings.endGroup();
        emit info("-settings R- ["+beginGroup+"] "+value+" ="+temp,0,100,0);
        return temp;
    }
    
    QString settings::dir_uitlezen()
    {
    #ifdef Q_OS_LINUX
        return readSettings("mapen_linux","dir_uitlezen","/home/user/Documenten/Uitlezingen/");
    #endif
    #ifdef Q_WS_WIN
    /* #elif Q_WS_WIN  "error" */
        return readSettings("mapen_windows","dir_uitlezen","C:/Documents/Uitlezingen");
    #endif
    }
    thread.h
    Code:
    #ifndef THREAD_H
    #define THREAD_H
    
    #include <QObject>
    #include <QThread>
    #include "settings.h"
    
    class Thread : public QThread
    {
        Q_OBJECT
    public:
        explicit Thread(QThread *parent = 0);
        ~Thread();
    
    protected:
        void run();
    
    signals:
        void info(QString,int,int,int);//text, red, green, blue
        void info_append(QString,int,int,int);//text, red, green, blue
    
    public slots:
        void start_uitlezen();
    
    private:
        settings Settings;
        QString dir_uitlezen;
        QString out_file;
        int exit;
        void readSettings();
    };
    #endif // THREAD_H
    thread.cpp
    Code:
    #include "thread.h"
    
    Thread::Thread(QThread *parent) :
        QThread(parent)
    {exit=1;}
    
    Thread::~Thread()
    {
        wait();
    }
    
    void Thread::run()
    {
        while (exit>0) {}
        exec();
    }
    
    /* => settings.h */
    void Thread::readSettings()
    {
        dir_uitlezen=Settings.dir_uitlezen();
    }
    
    void Thread::start_uitlezen()
    {
        emit info("start dir_uitlezen",0,0,100);
        readSettings();
        emit info("waarom geen '-settings R-' getoond?",255,0,0);
        emit info("done dir_uitlezen",0,0,100);
        emit info("nu wel ",0,100,100);
        exit=0;
    }
    sincerely
    BACKER

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×