crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> QThread&QProcess
Azazello
  опции профиля:
сообщение 1.5.2010, 23:41
Сообщение #1


Студент
*

Группа: Новичок
Сообщений: 16
Регистрация: 17.4.2010
Пользователь №: 1635

Спасибо сказали: 0 раз(а)




Репутация:   0  


Всем привет
Подскажите пожалуйста, что не так в коде ниже, и как можно сделать вывод процесса, запущенного в отдельном потоке в textEdit (как я понял, надо сначала передавать данные в основной поток)
Задача - запуск из GUI приложения процесса, в отдельном потоке и вывод полученной, в результате его выполнения, информации в textEdit.

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

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

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


void MainWindow::on_pushButton_clicked()
{
    ServerThread th;
    th.start();
}


mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>
#include <QProcess>
#include <QString>
#include "thread.h"

namespace Ui
{
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

private slots:
    void on_pushButton_clicked();
};

#endif // MAINWINDOW_H


thread.cpp
#include "thread.h"
#include "mainwindow.h"
#include <QProcess>
#include <QTextCodec>
#include <QDebug>

void ServerThread::run()
{
    process = new QProcess(this);
    process->setProcessChannelMode(QProcess::MergedChannels);
    connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(output()));
    process->start("uname");
    exec();
}
void ServerThread::output()
{
    QByteArray bytes = process->readAllStandardOutput();     //как передать вывод из созданного потока в основной?
}


thread.h
#ifndef THREAD_H
#define THREAD_H
#include <QThread>

class QProcess;

class ServerThread : public QThread
{
    Q_OBJECT

public:
     void run();

public slots:
     void output();

signals:

private:
    QProcess *process;
    
};

#endif // THREAD_H


На данный момент при попытке компиляции, программа вылетает. Если трассировать вручную, то отладчик пишет:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is ServerThread(0xbfffd8c4), parent's thread is QThread(0x804f818), current thread is ServerThread(0xbfffd8c4)
QThread: Destroyed while thread is still running
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 2.5.2010, 1:00
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Azazello @ 2.5.2010, 3:41) *
Cannot create children for a parent that is in a different thread.
нельзя создавать дочерний объект, находящийся в другом, от родителя, потоке

Цитата(Azazello @ 2.5.2010, 3:41) *
//как передать вывод из созданного потока в основной?
в дополнительном потоке посылать сигнал. А в основном создать слот и соединить его с этим сигналом
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Azazello
  опции профиля:
сообщение 2.5.2010, 1:11
Сообщение #3


Студент
*

Группа: Новичок
Сообщений: 16
Регистрация: 17.4.2010
Пользователь №: 1635

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Litkevich Yuriy @ 2.5.2010, 2:00) *
нельзя создавать дочерний объект, находящийся в другом, от родителя, потоке

Перевести-то я перевел, но только не понял, что этим мне хочет сказать компилятор...

Цитата(Litkevich Yuriy @ 2.5.2010, 2:00) *
в дополнительном потоке посылать сигнал. А в основном создать слот и соединить его с этим сигналом

Направление понял, буду пробовать. Спасибо.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 2.5.2010, 12:13
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Azazello @ 2.5.2010, 5:11) *
Перевести-то я перевел, но только не понял, что этим мне хочет сказать компилятор...
ну, схематично вот о чём:
QObject parentObject; // находится в одном потоке.
...
QObject child(parentObject); // находится в другом потоке
так делать нельзя
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Azazello
  опции профиля:
сообщение 2.5.2010, 13:29
Сообщение #5


Студент
*

Группа: Новичок
Сообщений: 16
Регистрация: 17.4.2010
Пользователь №: 1635

Спасибо сказали: 0 раз(а)




Репутация:   0  


А, все, дошло ) Спасибо!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Azazello
  опции профиля:
сообщение 2.5.2010, 16:00
Сообщение #6


Студент
*

Группа: Новичок
Сообщений: 16
Регистрация: 17.4.2010
Пользователь №: 1635

Спасибо сказали: 0 раз(а)




Репутация:   0  


Пытаюсь сделать вывод из дочернего потока в textEdit основного:

Добавил:
mainwindow.cpp
void MainWindow::on_pushButton_clicked()
{
    ServerThread th;
    connect(&th,SIGNAL(updateOutput(QString)),this,SLOT(setOutput(QString)));
    th.start();
}


mainwindow.h
private slots:
    void setOutput(QString msg);


Функцию run() переделал:
void ServerThread::run()
{
    QProcess process;
    process.setProcessChannelMode(QProcess::MergedChannels);
    connect(&process, SIGNAL(readyReadStandardOutput()), this, SLOT(output()));
    process.start("uname");
    exec();
}


thread.cpp
void ServerThread::output()
{
    QByteArray bytes = process->readAllStandardOutput();
    emit updateOutput(bytes);
}


thread.h
signals:
     void updateOutput(QString msg);


По нажатию на кнопку, прога вылетает. Я вот думаю, может процесс не успевает сделать вывод? Но ведь по идее для этого вызов идет через emit, или я что-то не правильно понимаю? :unsure:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 2.5.2010, 17:49
Сообщение #7


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Azazello @ 2.5.2010, 20:00) *
private slots:
у тебя слот не доступен для других объектов, он ЛИЧНЫЙ (private) данного класса. сделай его открытым (public)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Azazello
  опции профиля:
сообщение 2.5.2010, 18:03
Сообщение #8


Студент
*

Группа: Новичок
Сообщений: 16
Регистрация: 17.4.2010
Пользователь №: 1635

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Litkevich Yuriy @ 2.5.2010, 18:49) *
у тебя слот не доступен для других объектов, он ЛИЧНЫЙ (private) данного класса. сделай его открытым (public)


Юрий, спасибо за ответ.
Но, к сожалению, ситуацию это не меняет. Я пробовал объявлять его в public slots. Поток создается, но после этого приложение вылетает с "The program has unexpectedly finished."
Пробовал также запускать через отладчик, чтобы понять, в чем причина, но кроме того, что создается поток больше ничего не ясно...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 2.5.2010, 19:36
Сообщение #9


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


На сколько я понимаю, setOutput(QString) будет вызван в дочернем потоке, а в этом слоте по всей видимости идет обращение к GUI. С GUI нельзя работать вне основного потока, поэтому и получаем вылет.

Попробуй сделать следущие изменения в коде
connect(&th,SIGNAL(updateOutput(QString)),this,SLOT(setOutput(QString)), Qt::QueuedConnection);

private slots:
    void setOutput(const QString &msg);

signals:
     void updateOutput(const QString &msg);


Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 2.5.2010, 19:40
Сообщение #10


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(igor_bogomolov @ 2.5.2010, 23:36) *
, Qt::QueuedConnection)
по идее Qt сама выбирает тип соединения и указывать явно не нужно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.11.2024, 8:44