Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [qt4.5] QThread & QSqlQueryModel, аккуратно связать с интерфейсом 
:(
    Опции темы
zloyGamer
Дата 3.5.2009, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



над чтобы долгий процесс загрузки данных с БД выполнялся независимо от главного потока(чтоб приложение не подвисало), и время от времени выводилось сообщение о выполнении процесса..

щас решил сделать 2 потока: 
один будет посылать главному приложению сообщения о процессе выполнения а второй будет выполнять запросы к бд,
как только 2й поток закончит выполнение то оба потока завершают свою работу..

и вроде все честно сделал но проблема в том что работает оно нестабильно - всмысле при выполнении одних и тех-же запросов - результат выводится неполностью или выдаются ещё пустые строки и количество QSqlQueryModel::rowCount() выдается разное..

итак:
поток который сообщает о процессе выплнения главному приложению
Код

class MyThread : public QThread
{
    Q_OBJECT
  public:

    MyThread_exec   *m_MyThread_exec;  //поток который выполняет запрос

    QLineEdit       *m_QLineEdit_exec;  // куда выводим время вып-я
    QLineEdit       *m_QLineEdit_rows;  // кол-во стрк

    QTableView      *m_QTableView; 
    QString         m_sql;

    QTime           time;

  public:
    MyThread();
    ~MyThread();

    void set_sql (QTableView *p_QTableView,
                  QLineEdit *p_exec,
                  QLineEdit *p_QLineEdit_rows,
                  const QString &p_sql);

    void run();

  public slots:
    void  stopThread();

  signals:
    void set_time_text(const QString &p_txt);
    void set_rows_text(const QString &p_txt);

};
.....
///////////////////////////////////////////////////////////////////////////////////////////////////
MyThread::MyThread()
    :m_QTableView(0),
     m_MyThread_exec(new MyThread_exec(this)),
     m_QLineEdit_exec(0)
{
    qDebug() << "MyThread::MyThread() begin "<< QString::number( (int)this,16 );

    QObject::connect( m_MyThread_exec, SIGNAL(   finished ()) , this , SLOT(  stopThread()) );
    QObject::connect( m_MyThread_exec, SIGNAL(  terminated()) , this , SLOT(  stopThread()) );
    QObject::connect(            this, SIGNAL(  terminated()) , m_MyThread_exec , SLOT(  terminate()) );

}
///////////////////////////////////////////////////////////////////////////////////////////////////
MyThread::~MyThread()
{
  m_MyThread_exec->terminate();
  delete m_MyThread_exec;
  terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void MyThread::set_sql (QTableView *p_QTableView,
                        QLineEdit *p_exec,
                        QLineEdit *p_QLineEdit_rows,
                        const QString &p_sql)
{
    m_QTableView=0;
    m_QLineEdit_exec=p_exec;
    m_QLineEdit_rows=p_QLineEdit_rows;
    m_sql=p_sql;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void MyThread::stopThread()
{
  m_MyThread_exec->terminate ();
  terminate ();

  emit set_time_text( QString("%1").arg( ((double)time.elapsed())/1000,10,'f',2 ) );  //  выводим время вып-я
  emit set_rows_text( QString::number( m_MyThread_exec->m_model->rowCount() ) ); // кол-во строк

}
///////////////////////////////////////////////////////////////////////////////////////////////////
void MyThread::run()
{
  QObject::   connect( this, SIGNAL( set_rows_text(const QString &) ) , m_QLineEdit_rows , SLOT(  setText(const QString &) ) );
  QObject::   connect( this, SIGNAL( set_time_text(const QString &) ) , m_QLineEdit_exec , SLOT(  setText(const QString &) ) );
  m_MyThread_exec->start();
  time.start();
  while(1)
  {
    emit set_time_text( QString("%1").arg( ((double)time.elapsed())/1000,10,'f',2 ) );  //  выводим время вып-я
    emit set_rows_text( QString::number( m_MyThread_exec->m_model->rowCount() ) ); // кол-во строк
    msleep(50);

  }
  quit();
}
///////////////////////////////////////////////////////////////////////////////////////////////////



поток который выполняет запрос
Код

class MyThread_exec : public QThread
{
  public:

    QSqlDatabase      m_db;  //для этого потока создаем отдельное подключение к бд
    QSqlQueryModel   *m_model;


    MyThread         *m_MyThread;

    //MyThread_exec(QSqlQueryModel *p_model,MyThread *p_MyThread);

    MyThread_exec(MyThread *p_MyThread);
    ~MyThread_exec();
    void run();


};
...
///////////////////////////////////////////////////////////////////////////////////////////////////
MyThread_exec::MyThread_exec(MyThread *p_MyThread)
    :m_db(),
     m_model(new QSqlQueryModel() ),
     m_MyThread(p_MyThread)
{
    m_db = QSqlDatabase::addDatabase( tr("QODBC"),"connect_name__test_" );
}
///////////////////////////////////////////////////////////////////////////////////////////////////
MyThread_exec::~MyThread_exec()
{
    terminate();
    m_model->clear();
    delete m_model;
    m_db.close();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void MyThread_exec::run()
{

  m_db.close();
  m_db.setDatabaseName( "test_dbf" );

  if(!m_db.open())
  {
      QMessageBox::information(0, QString("err"),m_db.lastError().text());
      return ;
  }

  m_model->setQuery( m_MyThread->m_sql , m_db);  

  while (m_model->canFetchMore())
  {
    m_model->fetchMore();
    msleep(100);
  }
  quit();

}
///////////////////////////////////////////////////////////////////////////////////////////////////


и как все это выполняем:
Код

void MainWindow::pushButton_test_on_clicked()
{

  if(!m_thread)
  {
      m_thread = new MyThread();
      ui->tableView_all_records->setModel( m_thread->m_MyThread_exec->m_model );
  }

  // если не писать следующей строки то приложение иногда ведет себя ещё более неадекватно
  m_thread->m_MyThread_exec->m_model->moveToThread( QThread::currentThread() ); 


  m_thread->set_sql(ui->tableView_all_records,
                    ui->lineEdit_execute_time,
                    ui->lineEdit_rows,
                    "SELECT * FROM test_table"
                    );

  m_thread->start();

}



поток m_thread - уничтожаем тока после того как полученные данные уже будут не нужны,
т.к. m_model - которая отображается в QtableView - находится в его дочернем потоке и уничтожается вместе с ним!


вообщем проблема в том что в QtableView иногда выводится слишком много записей с пустыми строками, и иногда не все строки загружаются(выводятся пустыми)...
подскажите как корректно решить задачку?


PM MAIL   Вверх
zloyGamer
Дата 5.5.2009, 20:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



может есть пример чего то похожего или кто ните делал что т подобное
дайте код поковырять
PM MAIL   Вверх
zloyGamer
Дата 6.5.2009, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



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

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

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


 




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


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

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