Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поток [Qt], Передача значений 
V
    Опции темы
BIV
Дата 23.10.2010, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 219
Регистрация: 20.12.2007

Репутация: нет
Всего: 1



Всем доброе время суток!
У меня проект состоит из основного окна MainWindow и окна диалога Dialog. В оене диалога один компонент label.
Проблема в том, что в файле диалогового окна Dialog.cpp есть функция, которая очень долго выполняется. Получается такая ситуация, что при вызове из главного окна диалоговое окно, то диалоговое окно появиться не сразу, а спустя некоторое время. Пришел к выводу, что нужно создавать поток.
Идея такая: пусть запуститься сразу окно с просьбой подождать выполнение, и через некоторое время выводятся данные.
Вот возникает проблема передачи данных в label, так как Dialog и MyThread разные классы. Как это сделать?

Вот мои попытки реализовать свой замысел:
Заголовочный файл  dialog.h:
Код

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QThread>

namespace Ui {
    class Dialog;
    class MyThread;
}

class MyThread : public QThread
{
    Q_OBJECT

protected:
    void run();

public:
    explicit MyThread(QWidget *parent = 0);
    QString get();

private:
    Ui::Dialog *ui;
};

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
    QString get();

private:
    Ui::Dialog *ui;
};

#endif // DIALOG_H


dialog.cpp:
Код

#include "dialog.h"
#include "ui_dialog.h"
#include <QtNetwork>

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


}

void MyThread::run()
{
    QString str = get();
    if(str=="")ui->label->setText("Не определено");
    else ui->label->setText(str);
}



   QString MyThread::get()
    {
            QString strIP = "Выполнено соединение";
            return strIP;
    }

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




Это сообщение отредактировал(а) BIV - 23.10.2010, 22:33
PM MAIL   Вверх
null56
Дата 24.10.2010, 01:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 6
Всего: 12



Цитата(BIV @  23.10.2010,  17:54 Найти цитируемый пост)
Вот возникает проблема передачи данных в label, так как Dialog и MyThread разные классы. Как это сделать?

что тебе мешает сделать MyThread переменной - членом класса Dialog
Код

class MyThread : public QThread
{
//...
signals:
    void sendSignal(QString newLabelText);
};

class Dialog
{
public:
//...

public slots:
   void changeLabelText(QString newLabelText)
   {
    // РЕАЛИЗАЦИЯ В *.cpp
       m_Label.setText(newLabelText);
   }


private:
    MyThread m_DialogThread;
    QLabel m_Label;
};

и передавать данные, как сообщения (customEvent) или через механизм сигналов/слотов от нити к диалогу
Код

// соедини сигнал от потока со слотом диалога (можно прямо в конструкторе класса Dialog)
connect(&m_DialogThread, SIGNAL(sendSignal(QString)), SLOT(changeLabelText(QString)));

генери новые значения в потоке в виде сингалов, когда тебе это нужно
Код

void MyThread :: run()
{
//...
   QString new_label("Hi");
   emit  sendSignal(new_label);
}


ЗЫ: у Qlabel есть слот на изменение текста
Код

void    setText ( const QString & )

но тут объект передается по ссылке и без дополнительных средств синхронизации объекта QString тут не обойтись


Это сообщение отредактировал(а) null56 - 24.10.2010, 01:29
PM MAIL   Вверх
BIV
Дата 24.10.2010, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 219
Регистрация: 20.12.2007

Репутация: нет
Всего: 1



Ошибочки вылетают

Файл .h
Код

class Dialog : public QDialog
{
    ....

private:
    Ui::Dialog *ui;
    MyThread m_DialogThread;
};


Файл .cpp
Код

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog),
    m_DialogThread(new MyThread)
{
    ui->setupUi(this);
    connect(&m_DialogThread, SIGNAL(sendSignal(QString)), SLOT(changeLabelText(QString)));
}


Я наверно неправильно определяю ссылку на 4 строчке m_DialogThread(new MyThread)
Без этой записи тоже ругается. Как правильно задавать?
PM MAIL   Вверх
null56
Дата 24.10.2010, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 6
Всего: 12



оператор new нужен только для указателей на объекты. убери 4 строчку. если будут ошибки, опубликуй их сюда, мы не телепаты

PM MAIL   Вверх
BIV
Дата 24.10.2010, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 219
Регистрация: 20.12.2007

Репутация: нет
Всего: 1



Ошибка. Указывает на 3 строчку
undefined reference to 'MyThread::MyThread(QWidget*)'
collect2: Id returned 1 exit status

неопределенная ссылка на 'MyThread::MyThread(QWidget*)'
collect2: Идентификатор возвратил 1 статусу выхода

Это сообщение отредактировал(а) BIV - 24.10.2010, 15:16
PM MAIL   Вверх
null56
Дата 24.10.2010, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 6
Всего: 12



нет тела конструктора или не компилится cpp файл в котором определен конструктор класса MyThread. у вас конструктор где - нибудь определен?
Код

MyThread::MyThread(QWidget*)
{
 //...
}

PM MAIL   Вверх
BIV
Дата 24.10.2010, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 219
Регистрация: 20.12.2007

Репутация: нет
Всего: 1



Точно, конструктора небыло. Я добавил пустой конструктор. Оши бок не стало, но и лучше тоже

Вот файл .h
Код

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QThread>

namespace Ui {
    class Dialog;
    class MyThread;
}

class MyThread : public QThread
{
    Q_OBJECT

protected:
    void run();

public:
    explicit MyThread(QWidget *parent = 0);
    QString get();

signals:
    void sendSignal(QString newLabelText);

};

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
    QString get();

public slots:
   void changeLabelText(QString);

private:
    Ui::Dialog *ui;
    MyThread m_DialogThread;
};

#endif // DIALOG_H


Файл .cpp
Код

#include "dialog.h"
#include "ui_dialog.h"
#include <QtNetwork>

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    connect(&m_DialogThread, SIGNAL(sendSignal(QString)), SLOT(changeLabelText(QString)));
}

MyThread::MyThread(QWidget*)
{
    //Конструктор который ничего не делает
}

void Dialog::changeLabelText(QString newLabelText)
{
     ui->label->setText(newLabelText);
}


void MyThread::run()
{
    //...
    QString str = get();
    //ui->label->setText(str);
    emit  sendSignal(str);
}

QString MyThread::get()
    {
        QString strIP;
        QNetworkAccessManager manager;
        QNetworkReply *reply = manager.get( QNetworkRequest( QUrl( "http://www.grio.ru/myip.php" ) ) );

        QEventLoop loop;
        QObject::connect( reply, SIGNAL( finished() ), &loop, SLOT( quit() ) );
        loop.exec();

        // Проверяем состояние ответа
        if( reply->error() != QNetworkReply::NoError )
            return strIP="Не определено";    // Ошибка

        // Читаем полученные данные в data
        QByteArray data = reply->readAll();

        // Разбираем полученные данные, находим свой ip и возвращаем его
        strIP = QString(data);
                return strIP;
    }

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

PM MAIL   Вверх
null56
Дата 24.10.2010, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 6
Всего: 12



dialog.h (классы диалога и дочернего потока)
Код

#include <QDialog>
#include <QThread>

namespace Ui {
    class Dialog;
}

class MyThread : public QThread
{
    Q_OBJECT

public:
    MyThread() {}
    ~MyThread() {}
    QString get();
    void run();

signals:
    void sendSignal(QString newLabelText);

};

class Dialog : public QDialog {
    Q_OBJECT
public:
    Dialog(QWidget *parent = 0);
    ~Dialog();
    void show();

protected slots:
   void changeLabelText(QString);

private:
    Ui::Dialog *ui;
    MyThread m_MyThread;

};


dialog.cpp
Код

// тут делай свои действия
QString MyThread :: get()

    QString str("hi");
    return str;
}

void MyThread :: run()
{
    QString new_label_text = get();
    emit sendSignal(new_label_text);
}

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    connect(&m_MyThread, SIGNAL(sendSignal(QString)), SLOT(changeLabelText(QString)));
}

// перегрузим метод вызова диалога, предворив сам вызов запуском потока
void Dialog::show()
{
    m_MyThread.start();
    QDialog :: show();
}



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

// обработка слота, присваиваем метке полученную из потока строку
void Dialog::changeLabelText(QString str)
{
    ui->label->setText(str);
}


main.cpp
Код

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();
    return a.exec();
}

PM MAIL   Вверх
BIV
Дата 24.10.2010, 23:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 219
Регистрация: 20.12.2007

Репутация: нет
Всего: 1



Сделал все как Вы писали, но  проблема никак не решается: не срабатывает void MyThread :: run()
Я решил отправить мою заготовку, так как по нему, думаю, будет проще решать проблему. Значит основная проблема, это сразу при вызове открыть диалоговое окно, а уже как прога получит данные, тогда и внесет.
Моя программка еще разрабатывается, так что там еще много чего пока не работает.

http://file.qip.ru/file/WW-UCZc1/Admin1.html ( 33.31 Kb )

Запуск того диалогового окна через меню Сервис->Внешний IP
PM MAIL   Вверх
null56
Дата 24.10.2010, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 6
Всего: 12



вы диалог вызываете через exec, в моем примере я перегружал метод show
добавьте перегрузку метода exec в dialog
Код

// *.h
class Dialog
{
 ...
 int exec();
};

// *.cpp
int Dialog::exec()
{
    m_DialogThread.start();
    return QDialog :: exec();
}

PM MAIL   Вверх
BIV
Дата 24.10.2010, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 219
Регистрация: 20.12.2007

Репутация: нет
Всего: 1



Ууффф, что надоsmile
Спасибо, Вам большое за такую колосальную работу. Очень помогли
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0762 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.