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:
[B]CODE[/B]
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
[/CODE]
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();
}
[/CODE]
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
[/CODE]
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());
}
[/CODE]
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
[/CODE]
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
}
[/CODE]
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
[/CODE]
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);
}
[/CODE]
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
Re: Signals_and_Slots_on_QThread_wit_sired_class
[QUOTE]
I'm unable to emit a signal from settings if it's been been called from a sub thread.
[/QUOTE]
I think signal is emitted by settings in the thread, but you are not listening for it!
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);
[/CODE]
not listening
and
[CODE]
connect(&thread, SIGNAL(info(QString,int,int,int)),
this, SLOT(print(QString,int,int,int)),
Qt::AutoConnection);
[/CODE]
not listening
:confused:
[QUOTE]@doc.qt.nokia.com
A class which emits a signal neither knows nor cares which slots receive the signal.[/QUOTE]
Signal OK
Slot OK
Meta-Object problem?
I forget what?
sincerely
BACKER
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
[/CODE]
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();
}
[/CODE]
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
[/CODE]
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());
}
[/CODE]
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
[/CODE]
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
}
[/CODE]
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
[/CODE]
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;
}
[/CODE]
sincerely
BACKER