Russian Qt Forum
Декабрь 27, 2024, 13:44 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Зависание GUI  (Прочитано 16463 раз)
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« : Март 20, 2012, 11:35 »

Доброго дня! Есть такая проблемка: по сети, в отдельном потоке приходят данные, заполняя глобальную структуры данных, объявленную как extern! После того как вся инфа была получена отсылается сигнал, связанный со слотом в главном потоке, который отрисовывает полученную инфу из глобальной структуры! При этом сигналы невсегда доходят и интерфейс программы висит! Может нужно заменить сигналы на события? Если да, то как это сделать.. нужно реализовывать собственный класс событий??
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Март 20, 2012, 11:36 »

Код показывай.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #2 : Март 20, 2012, 11:56 »

код достаточно большой.. основные выдержки:
прием данных

Код:
void TSignalReceiver::run( )
{
        int ioSize = 0;

        bool timedOut = false;
        static uint azimuth = 0;

        QString strPortData  = "3111";

        while ( !isDone( ) )
        {
                if ( paused( ) )
                {
                        // если поток приостановлен - ждем...
                        currentThread( )->msleep( pausedThreadDelay );
                        continue;
                }
         
               CNetworkStd::closeSocket( socket );
               socket = CNetworkStd::connectClientTcp(settings.stationIp.toAscii( ),
                                                              strPortData.toAscii( ),
                                                                   1000, &timedOut );

                if ( socket == invalid_socket )
                {
                        // обработка...
                        continue;
                }

                 while ( !isDone( ) )
                {
                        if ( paused( ) )
                        {
                                // если поток приостановлен - ждем...
                                currentThread( )->msleep( pausedThreadDelay );
                                continue;
                        }

                        if ( CNetworkStd::recvData( socket,
                                                    reinterpret_cast< char* >( &packetFromHw ), // структура, куда записываютс данные
                                                    sizeof( packetFromHw ),
                                                    ioSize,
                                                    3000,
                                                    &timedOut ) == false )
                        {
                                if ( timedOut )
                                {
                                        // обработка
                                        continue;
                                }
             
                        }
                         qDebug() << "Az = " << packetFromHw.Az; // эта строка выводится каждый раз, когда пришли данные
                         emit onRecvSignal(); // если данные получены отослать сигнал !!!!!!


конект сигнала со слотом
Код:
connect(tSignReceiv,SIGNAL(onRecvSignal()),indWin,SLOT(slotDrawIndicat()));

// отрисовка
Код:
void COpenGlEngine::slotDrawIndicat()
{
     
       int az =  packetFromHw.Az;
       qDebug() << "Az = " << az; // а здесь уже данные выводятся не каждый раз, а через 3-4 раза..
                                            // хотя сигнал отсылается каждый раз, как данные в полном объеме получены

       ...
}
Записан
V1KT0P
Гость
« Ответ #3 : Март 20, 2012, 11:59 »

Так и не понял проблема в том что только сигнал не доходит или GUI зависает. Или и то и другое? А как ты в отдельный поток код обработки выносишь?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #4 : Март 20, 2012, 12:02 »

Что-то у тебя напутано. Отправляй структуру в сигнале и лови ее в слоте, а не используй глобальную структуру.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
mutineer
Гость
« Ответ #5 : Март 20, 2012, 12:03 »

и больше кода не помешает
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #6 : Март 20, 2012, 12:09 »

Так и не понял проблема в том что только сигнал не доходит или GUI зависает. Или и то и другое? А как ты в отдельный поток код обработки выносишь?

и сигнал не доходит, и все элементы интерфейса не реагируют на нажатие, всё дико висит! "А как ты в отдельный поток код обработки выносишь?" в каком плане? из главного потока запускается поток TSignalReceiver и там принимаются данные..! с этим проблем нет, а вот в том что они не всегда читаются.. ибо сигнал не всегда доходит - проблема!
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #7 : Март 20, 2012, 12:12 »

а каким образом передать структуры в сигнале и принять ее в слоте?
структура
Код:
struct dataPacket
        {
            dataPacket( ) : Az( 0 ), TpCnt( 0 ), nagcFactor( 0 ), isJammer( 0 )
            {
                    qMemSet( data, 0, sizeof( uchar ) * distancePoints );
            }

            alt_u16 Az;
            alt_u16 TpCnt;
            alt_u8  data[2400];
            alt_u8  nagcFactor;
            alt_u8  isJammer;
            alt_8   dummy[ 2 ];
            
        };

дойдет ли она корректно и всегда, как только получены данные, если даже просто сигнал не всегда доходит?
« Последнее редактирование: Март 20, 2012, 12:13 от Vladimir » Записан
V1KT0P
Гость
« Ответ #8 : Март 20, 2012, 12:22 »

Так и не понял проблема в том что только сигнал не доходит или GUI зависает. Или и то и другое? А как ты в отдельный поток код обработки выносишь?

и сигнал не доходит, и все элементы интерфейса не реагируют на нажатие, всё дико висит! "А как ты в отдельный поток код обработки выносишь?" в каком плане? из главного потока запускается поток TSignalReceiver и там принимаются данные..! с этим проблем нет, а вот в том что они не всегда читаются.. ибо сигнал не всегда доходит - проблема!
TSignalReceiver - наследуется от QThread-а? Если да то ты его после объявления moveToThread-ил сам в себя?
Записан
mutineer
Гость
« Ответ #9 : Март 20, 2012, 12:23 »

Если да то ты его после объявления moveToThread-ил сам в себя?

Вот не надо так делать
Записан
V1KT0P
Гость
« Ответ #10 : Март 20, 2012, 12:29 »

Если да то ты его после объявления moveToThread-ил сам в себя?

Вот не надо так делать
Да знаю я уже =). Но он же мог вот так сделать и наступить на грабли.
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #11 : Март 20, 2012, 12:33 »

Что значит "moveToThread-ил сам в себя"??
а наследуется так
Код:
class TSignalReceiver : public TAbstractThread
        {
                ....
         }
class TAbstractThread : public QThread
        {
                  ...
        }

Записан
mutineer
Гость
« Ответ #12 : Март 20, 2012, 12:34 »

Покажи хедеры обоих классов (прием данных и гуй), как они создаются и как связываются
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #13 : Март 20, 2012, 12:48 »

class TSignalReceiver описание
Код:
class TSignalReceiver : public TAbstractThread
        {
                Q_OBJECT

        public:
                TSignalReceiver( const QString& name, QObject* parent = 0 );
                virtual ~TSignalReceiver( );
                virtual void stop( );


        signals:
                void togglePeriod( );

                void setRadiation( int );

                void onRecvSignal();

        protected:
                virtual void run( );

        private:
                networkEvents netEvt;
                network::socket_type socket;
        };
Конструктор
Код:
TSignalReceiver::TSignalReceiver(const QString& name, QObject* p ) :
                                TAbstractThread( name, p ), socket( 0 )
{
       
}

class TAbstractThread описание
Код:
class TAbstractThread : public QThread
        {
                Q_OBJECT

        public:
                TAbstractThread( const QString& name, QObject* parent = 0 );
                virtual ~TAbstractThread( ) = 0;
             
                virtual void stop( );
               
                virtual bool isDone( ) const;
                virtual void setPause( bool p );
                virtual bool waitForPaused( uint msec = -1 );

               
                virtual bool paused( ) const;
                virtual QString name( ) const;

        signals:
               
                void setGlobalStatus( int sys, int state );
             
                void updateStationStatus( const SStatus& st );
        private:
                volatile bool done__;
                volatile bool pause__;

                QString name__;

                mutable QMutex mut__;
                mutable QWaitCondition wcPause__;
        };

В главной форме окна создается 
tSignReceiv = new TSignalReceiver( "RcvSig", this );
там же и связывается

connect(tSignReceiv,SIGNAL(onRecvSignal()),indWin,SLOT(slotDrawIndicat()));

Проект достаточно большой поэтому сложно выложить весь код подробно, будет много! Да, кстати, программа под Linux на Qt 4.8!




Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #14 : Март 20, 2012, 12:55 »

Закомментировал отрисовку и картина вообще удивлять стала! Чередование сообщений получается очень разное:
QDebug() << " в потоке сразу после приема данных";
QDebug() << " в слоте отрисовки";

Хотелось бы видеть:
QDebug() << " в потоке сразу после приема данных";
QDebug() << " в слоте отрисовки";
QDebug() << " в потоке сразу после приема данных";
QDebug() << " в слоте отрисовки";
QDebug() << " в потоке сразу после приема данных";
QDebug() << " в слоте отрисовки";

А получается:
QDebug() << " в потоке сразу после приема данных";
QDebug() << " в слоте отрисовки";
QDebug() << " в слоте отрисовки";
QDebug() << " в слоте отрисовки";
QDebug() << " в слоте отрисовки";

QDebug() << " в потоке сразу после приема данных";
QDebug() << " в потоке сразу после приема данных";
QDebug() << " в слоте отрисовки";

В общем различные комбинации, но не последовательно одна за другой..
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.136 секунд. Запросов: 22.