crossplatform.ru

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

 
Ответить в данную темуНачать новую тему
> QTableWidget + boost::thread
mrjoker
  опции профиля:
сообщение 9.7.2008, 11:17
Сообщение #1


Новичок


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

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




Репутация:   0  


Помогите, пожалуйста, решить такую проблему:
Мне нужно выводить информацию в QTableWidget в потоке boost::thread. Не могли бы вы подсказать, как это сделать?
Поток должен быть только boost'овский. Если с QTableWidget - проблемно, то тогда с каким объектом и главное как?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrew Selivanov
  опции профиля:
сообщение 9.7.2008, 13:03
Сообщение #2


Участник
**

Группа: Участник
Сообщений: 249
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 3

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




Репутация:   6  


Цитата(mrjoker @ 9.7.2008, 12:17) *
Помогите, пожалуйста, решить такую проблему:
Мне нужно выводить информацию в QTableWidget в потоке boost::thread. Не могли бы вы подсказать, как это сделать?
Поток должен быть только boost'овский. Если с QTableWidget - проблемно, то тогда с каким объектом и главное как?

думаю смешивать работу с потоками двух разных либ не очень хорошая идея... ну наверное поток в котором у тебя живет QTable должен дергать поток boost на предмет готовы ли данные, если данные готовы, копировать их к себе и отображать. Можно сделать это через volatile переменную и sleep или средства более высокого уровня (boost::condition...)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 9.7.2008, 14:10
Сообщение #3


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

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




Репутация:   40  


Пускай так ты создаешь свой виджет:
QTableWidget *tableWidget;
tableWidget = new QTableWidget(12, 3, this);
После чего передаешь в поток указатель tableWidget и работаешь с ним:
QTableWidgetItem *newItem = new QTableWidgetItem(tr("%1").arg(pow(row, column+1)));
tableWidget->setItem(row, column, newItem);
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mrjoker
  опции профиля:
сообщение 9.7.2008, 15:10
Сообщение #4


Новичок


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

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




Репутация:   0  


Цитата(ViGOur @ 9.7.2008, 15:10) *
Пускай так ты создаешь свой виджет:
QTableWidget *tableWidget;
tableWidget = new QTableWidget(12, 3, this);
После чего передаешь в поток указатель tableWidget и работаешь с ним:
QTableWidgetItem *newItem = new QTableWidgetItem(tr("%1").arg(pow(row, column+1)));
tableWidget->setItem(row, column, newItem);


Я создал свой класс CMyTableWidget1
 
class CMyTableWidget1 : public QTableWidget
{
    Q_OBJECT;
    
    bool                m_stop;

public :
    CMyTableWidget1(QWidget *parent = 0):QTableWidget(0,2,parent)
    {
        this->m_stop = false;
                 // Описываю заголовки столбцов
                 // ....
    }
    
    void RowToTable()
    {
        int i=0;
        QTableWidgetItem *item;
        QString    str;

        while (!m_stop)
        {
            this->insertRow(0);
            item = new QTableWidgetItem();
            str.setNum(i);
            item->setText(str);
            this->setItem(0,0,item);
            i++;
        }
    }
};


А в основном классе окна делаю следующее:
 Table3 = new CMyTableWidget1(ui.centralWidget);
    Table3->setGeometry(QRect(30, 150, 241, 200));

        boost::thread *th = new boost::thread(boost::bind(&CMyTableWidget1::RowToTable,this->Table3));


Тогда после запуска программы, в основном окне появляется таблица со столькими строками, сколько успело появится до появления окна на экране. Далее при любом действии типа "скрыл окно-развернул окно", информации переписывается, а количество строк не изменяется.

Сообщение отредактировал mrjoker - 9.7.2008, 15:11
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 9.7.2008, 15:12
Сообщение #5


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

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




Репутация:   40  


Так ты сам изменяй их количество. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mrjoker
  опции профиля:
сообщение 9.7.2008, 15:19
Сообщение #6


Новичок


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

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




Репутация:   0  


Цитата(ViGOur @ 9.7.2008, 16:12) *
Так ты сам изменяй их количество. :)


Что ты имеешь ввиду? Вызывать repaint? Это не получится, т.к. не в основном потоке.

Сообщение отредактировал mrjoker - 9.7.2008, 15:20
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 9.7.2008, 16:30
Сообщение #7


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

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




Репутация:   40  


Вот, я набросал пример как:
#include <qtgui>

class CMyTableWidget1;

class MyThread : public QThread
{
    Q_OBJECT

private:
    CMyTableWidget1 *m_ptw;

public:
    MyThread( CMyTableWidget1 *ptw):m_ptw(ptw)
    {
    }

    void run();

    static void mysleep ( unsigned long sec)
    {
        sleep( sec);
    };
};


class CMyTableWidget1 : public QTableWidget
{
    Q_OBJECT;
    
    bool                m_stop;

public :
    CMyTableWidget1(QWidget *parent = 0):QTableWidget( 0,2,parent)
    {
        connect( this, SIGNAL( addMyRow( int, int, QTableWidgetItem *)),
                 this, SLOT( addRow( int, int, QTableWidgetItem *)));
        this->m_stop = false;
                 // Описываю заголовки столбцов
                 // ....
    }
    
    void RowToTable()
    {
        int i=0;
        QTableWidgetItem *item;
        QString    str;

        while (!m_stop)
        {
            int nRow = rowCount();
            item = new QTableWidgetItem();
            str.setNum( i);
            item->setText( str);
            
            emit addMyRow( nRow, 0, item);
            i++;
            MyThread::mysleep( 1);
        }
    }

signals:
    void addMyRow( int nRow, int nCol, QTableWidgetItem *pItem);

private slots:
    void addRow( int nRow, int nCol, QTableWidgetItem *pItem)
    {
        setRowCount( nRow + 1);
        setItem( nRow, nCol, pItem);
    }
};

void MyThread::run()
{
        m_ptw->RowToTable();
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    CMyTableWidget1 *ptw = new CMyTableWidget1( 0);

    MyThread thread( ptw);
    thread.start();

    ptw->show();

    return a.exec();
}

#include "main.moc"
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 9.7.2008, 21:15
Сообщение #8


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

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




Репутация:   17  


В Qt с виджетами можно работать только в одном потоке - главном.
Если нужно что-то с ними делать в других потоках, то надо или создавать общие данные и синхронизировать их, или посылать Qt-ёвые сигналы или события.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
31512
  опции профиля:
сообщение 10.7.2008, 7:04
Сообщение #9


Студент
*

Группа: Новичок
Сообщений: 26
Регистрация: 13.3.2008
Из: Красноярск
Пользователь №: 119

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




Репутация:   0  


Есть 2 способа работать с виджетами в потоке:
1. Создавать переменные и из потока заполнять их значениями. Потом вызывать метод типа Refresh и читать эти переменные в табличку.
2. По книжке Жасмин, Бланшет и др. (стр 464-465)
Пусть в потоке есть метод типа
void SomeThread::WriteToTable(const QString &P1, const int &P2, const double &P3)
{
     QMetaObject::invokeMethod(WidgetWhereTablePlaced,
                                               "WriteToTable",
                                               Qt::QueredConnection,
                                               Q_ARG(QString, P1),
                                               Q_ARG(int, P2),
                                               Q_ARG(double, P3));
}

где "WriteToTable" - имя метода, в классе WidgetWhereTablePlaced (это форма, фрейм, диалог). В классе WidgetWhereTablePlaced должен быть метод с названием WriteToTable с теми же параметрами, в котором и происходит заполнение таблички.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 27.12.2024, 2:58