Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [qt] пара общих вопросов 
:(
    Опции темы
gordmiand
Дата 20.5.2010, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



1. Есть проект, расположенный в папке Papka1…в дополнение к нему я создал (типа “Класс формы Qt Designer ”) еще одну ui-форму с ее классом в папке Papka1/pap2 – вроде все нужные файлы  (cpp, h, ui –файлы) вновь созданной формы хранятся в указном месте (папке pap2), но почему при компиляции проги ui-файл хидера новой формы каждый раз создается (???) не в папке pap2, а в главной папке приложения (Papka1)? Как это исправить, чтобы этот файл создавался в нужной мне папке (pap2)? Естес-но если я в проге при подключении этого ui-файла хидера новой формы задам путь к ..//pap2, то прога будет нечувствительна к изменениям состава виджетов на этой форме, так как все-таки будет браться (???) этот ui-h-файл из папки Papka1… заморочился таким вопросом по причине того, что просто хочу разложить, так сказать, все по полочкам – все файлы проекта – в одной папке, все вспомогательное – в другой… 
2. как мне сделать бесконечный цикл, чтобы он запускался сразу после загрузки проги? в конструкторе main-класса это сделать нельзя - прога подвисает на этапе запуска...
сначала я таймер использовал для этого - в событии обработки таймера (TimerEvent) у меня происходит прием данных по сети со своим внутренним таймаутом - и при совместном использовании таймера и таймаута в функции чтения данных из сети, судя по каким-то судорожным принтам приходящей информации, этот прием данных выполняется как-то прерывисто что ли...
оптимально и наиболее надежно все это сделать обычным вечным циклом с таймайтом при чтении данных из сети, но как сие осуществить при возникновении вышеуказанной проблемы подвисания проги сразу при ее загрузке...

PM MAIL   Вверх
ecspertiza
Дата 21.5.2010, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



1. В *.pro файле прописываешь 
Код

UI_HEADERS_DIR = tmp/ui/include
UI_SOURCES_DIR = tmp/ui/src


Ну и там пути естественно какие тебе удобны


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


--------------------
С уважением,
мастер конфетного цеха!

онлайн компилер
залип
PM MAIL   Вверх
Remiznik
Дата 21.5.2010, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



2. создай класс который загружается во время входа в программу и запусти в нём цикл. 
PM MAIL   Вверх
gordmiand
Дата 21.5.2010, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



ecspertiza:
по п.1 - все понял - обяз-но поробую....
по п.2. да уж куда проще:
если взять консольное приложение:
Код

int  main(int argc, char *argv[])
{
int i=1;

while (i>0)
{
    read_from_net((char *)&buf, len, 100); // своя рабочая функция - включает в себя создание сокета, ioctl, bind и т.д.    
    …
    printf(...); 
    sleep(1);
    i++;
}

return 0;
}

то есть задача стояла следующая – я бесконечное число раз с заданным таймаутом (100 мс) читаю данные из сетевого буфера...
а как мне такой while сделать в гуишном кутэ? в консоли (см. пример выше) все окей работает...
если поставить такой while в сигнал какого-либо виджета (допустим онклик кнопки) или в конструктор главной формы, то прога вообще подвисает...вместо самого while-a пробовал использовать таймер с интервалом аж 1 мс (ну типа самое минимальное, аля как темп работы while-а), а тело while-a запихнул соответственно в timerEvent, но судя по печатям чего-либо в этом цикле он срабатывает неправильно – то есть значения выводятся верные, но непонятно с каким временным интервалом (1 мс + 100 мс ?) и печатаются сообщения неравномерно (то вообще ничено не принтуется, а то сразу несколько строк с данными)  


Это сообщение отредактировал(а) gordmiand - 21.5.2010, 23:12
PM MAIL   Вверх
gordmiand
Дата 21.5.2010, 23:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Remiznik: поправьте (напишите верно) Вашу идею в приложенной программке....и подскажите функцию кутей аля Sleep для вывода данных с задержкой...

Это сообщение отредактировал(а) gordmiand - 21.5.2010, 23:50

Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  my_gui.rar 8,83 Kb
PM MAIL   Вверх
borisbn
Дата 22.5.2010, 06:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Цитата
.и подскажите функцию кутей аля Sleep

У кутей нет Sleep, поэтому я себе сделал маленький классик

Код

#ifndef SLEEPER_H_INCLUDED
#define SLEEPER_H_INCLUDED

#include <QThread>
class Sleeper : public QThread
{
public:
    static void go( int ms ) { msleep( ms ); }
};
#endif // SLEEPER_H_INCLUDED

и использую его
Код

Sleeper::go( 100 ); // sleep 100 мс




--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
gordmiand
Дата 22.5.2010, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



borisbn: 
спасибо за классик, только непонятно почему нельзя напрямую использовать  функцию msleep, если с помощью нее, как я понял, и реализуется задержка в Вашем методе go? и что это за метод - msleep?

и все-таки - как же в гуищном qt-проекте реализовать рабочий (независающий) бесконечный цикл?
PM MAIL   Вверх
borisbn
Дата 22.5.2010, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Цитата(gordmiand @  22.5.2010,  14:10 Найти цитируемый пост)
почему нельзя напрямую использовать  функцию msleep

msleep - статическая protected-функция класса QThread
Цитата(gordmiand @  22.5.2010,  14:10 Найти цитируемый пост)
в гуищном qt-проекте реализовать рабочий (независающий) бесконечный цикл

гуишный поток обработки сообщений сделан примернотак (псевдо-код)
Код

если в очереди есть сообщение
    обработать сообщение
    удалить сообщение из очереди
конец если

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

Это сообщение отредактировал(а) borisbn - 22.5.2010, 19:56


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
gordmiand
Дата 23.5.2010, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



borisbn: то есть простой бесконечный while напрямую (прямо в mainwindow.cpp) сделать нельзя?
типа 
Код

int i=0;

while (i>=0)    
{

         // что-то делаем
          printf (" " ); 
    
i++;
}

в консольном приложении такой циклик нормально работает...
то есть мне надо этот цикл запихнуть в отдельный QThread-поток (класс-наследник от QThread) и вызывать его из основного main-потока???
PM MAIL   Вверх
gordmiand
Дата 23.5.2010, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Код

                                                                        klass2.h:
#include <QThread>
class klass2: public QThread 
{
public:
    klass2();
    int perem;
    void run();
};

///////////////////////////////////////////////////////
                                                                        klass2.cpp:
#include "klass2.h"
klass2::klass2()
{   }

void klass2::run()
{
       int i=1;
       perem=15;

/*
        while (i>0)
        {
            perem=5;
           i++;
        }
*/
}

                                                                             mainwindow.h
...
#include "klass2.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

    klass2 *kl2;
….
}
                                                                            mainwindow.cpp

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

        kl2 = new klass2;

        kl2->start();     //или  QThread::IdlePriority);

        ui->listWidget->addItem(QString::number(kl2->perem));
}

2 вопроса:
1. Почему значение perem=0, а не 15, как задано в методе run? Как будто он вообще не запускается, хотя вроде должен был после вызова метода start сего класса (kl2->start();)?
2. как мне сделать вывод в listWidget главной формы циклически бесконечно задаваемых
(while (i>0) …) значений (=5) переменной perem из метода run класса klass2? 


Это сообщение отредактировал(а) gordmiand - 23.5.2010, 21:29

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  my_gui.rar 9,13 Kb
PM MAIL   Вверх
borisbn
Дата 24.5.2010, 06:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Поток запускается не сразу, а с какой-то задержкой, поэтому в переменной ноль (хотя мог быть и мусор). Так, как у тебя сделано, делать нельзя. Представь, что у тебя не целочисленная переменная, а структура типа "имя", "фамилия". Может получиться, что ты отобразишь имя одного человека, а фамилию другого. Чтобы этого не получилось используй QMutex для блокирования данных, используемых одновременно в двух потоках.
Ещё можно в QThread-классе добавить сигнал, который будет передавать значение переменной гуишному потоку, а в форме создать слот, принимающий и отображающий переменную. 
И не забудь связать этот сигнал с гуишным слотом

Код

// klass2.h
class klass2: public QThread 
{
public:
    klass2();
    int perem;
    void run();
signals:
    void drawPerem( int );
};
// klass2.cpp
void klass2::run()
{
       int i=1;
       perem=15;

       emit drawPerem( perem );
}
//mainwindow.h

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

    klass2 *kl2;
public slots:
    void onDrawPerem( int );
}
//mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

        kl2 = new klass2;
        connect( kl2, SIGNAL( drawPerem( int ) ), SLOT( onDrawPerem( int ) ) );

        kl2->start();     //или  QThread::IdlePriority);

}

void MainWindow::onDrawPerem( int perem )
{
        ui->listWidget->addItem( QString::number( perem ) );
}

как-то так

Это сообщение отредактировал(а) borisbn - 24.5.2010, 08:33


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
gordmiand
Дата 24.5.2010, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



понятно...то есть получается, что получить доступ к данным, изменяющимся в методе run, одного потока из другого можно только через сигналы (то есть передавая/принимая нужные данные через connect - т.е. соединение типа сигнал-слот),  а "по-простому" (получить значение нужной переменной стороннего класса через его экземпляр) нельзя, хотя поток тоже является классом (наследником QThread), a run - методом? 
а если я хочу пользоваться в главном потоке приложения не одной переменной из стороннего потока (klass2), а, допустим, десятком данных (значениями массивов, структур этого потока), то мне всех их надо запихивать в сигнал (в виде целикового массива)? 
но сторонний поток мне в любом случае нужен (для ускорения работы проги)...
PM MAIL   Вверх
borisbn
Дата 24.5.2010, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Цитата(gordmiand @  24.5.2010,  10:19 Найти цитируемый пост)
доступ к данным, изменяющимся в методе run, одного потока из другого можно только через сигналы

нет. не только. это один из способов. другой способ - использовать QMutex для блокирования данных, используемых одновременно в двух потоках.
Код

// klass2.h
class klass2: public QThread 
{
public:
    klass2();
    int perem;
    int array[ 1000 ];
    void run();

    QMutex m_dataLocker;
    int getPerem();
    void getArray( int * a );
};
// klass2.cpp
void klass2::run()
{
       int i=1;
...
       m_dataLocker.lock();
       perem=15;
       array[ i ] = 10;
       m_dataLocker.unlock();
...
}
int klass2::getPerem()
{
       QMutexLocker locker( &m_dataLocker );
       return perem;
}
void klass2::getArray( int * a )
{
       QMutexLocker locker( &m_dataLocker );
       memcpy( a, array, sizeof( array ) );
}

//mainwindow.cpp
void MainWindow::doSomething()
{
        ui->listWidget->addItem( QString::number( kl2->getPerem() ) );
        int array[ 1000 ];
        kl2->getArray( array );
}


Это сообщение отредактировал(а) borisbn - 24.5.2010, 14:24


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
gordmiand
Дата 24.5.2010, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



вау...как все сложно - какой-то QMutexLocker locker,  memcpy...
можно получить хотя бы краткое пояснение сего кода?

по поводу предыдущего (перед мутексами) сообщения - все работает, спасибо за подсказку.
То есть получается, что данная переменная perem будет доступна в классе (mainwindow) главного потока  только в слоте (PotokPerem), в который она была „передана“?  
Код

#include <QThread>
class klass2: public QThread                               
{
    Q_OBJECT
public:
    klass2();
    int perem;
    void run();
signals:
      void ShowPer(int);
};

///////////////////////////////////////////////////////
klass2::klass2()     
{
     perem=0;
}


void klass2::run()
{
       int i=1;
       perem = 11;
      
        emit  ShowPer( 55 );
}
///////////////////////////////////////////////////////

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    klass2 *kl2;
public slots:
    void PotokPerem(int);
...
};
///////////////////////////////////////////////////////

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


             kl2 = new klass2;
             kl2->start();        

             connect(kl2,    SIGNAL(ShowPer(int)),     this,   SLOT(PotokPerem(int))  );
}

void MainWindow::PotokPerem(int )
{
       ui->listWidget->addItem(QString::number(kl2->perem));
}
///////////////////////////////////////////////////////

Почему, если задать в качестве аргумента для emit ShowPer не perem, а, допустим, любую константу (55) или что-то еще, но не perem, то все равно при выводе (слот PotokPerem) в главном потоке значение переменной perem = 11, как и задано в методе run, но я же вроде как не передаю эту переменную в сигнале (а, например, задана отвлеченная константа 55) в слот главного потока... 
Непонятно зачем здесь вообще нужны параметры  для сигнала ShowPer и слота PotokPerem, когда и без них все работает (в главном потоке выводится значение (11) переменной perem)???

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


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

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



memcpy - это так модно массивы копировать (не все!). Про мутексы полно информации в интернетах. Можно воспользоваться и другими, системными, приемами синхронизации. Например на семафорах можно сделать, чтобы данные могли читаться одновременно из N процессов/потоков, а писались синхронно (дождавшись завершения их чтения).

Добавлено через 20 секунд
В Qt оказывается тоже семафоры есть...


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

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

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


 




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


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

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