Форум программистов CodeGuru
18 Январь 2018, 10:10:22 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: IDLE в Qt  (Прочитано 15884 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Aeron
Пользователь
***
Офлайн Офлайн

Сообщений: 49


Просмотр профиля
« : 11 Январь 2007, 00:14:12 »

Приветствую !

Начал немного писать под Linux. Поставил KDE, а под ним KDevelop.
Пытаюсь писать GUI-приложения с использованием библиотеки Qt.

Теперь о проблемах. В Windows есть такое понятие как idle. Например, в MFC во время idle обновляются состояния меню, тулбаров, и.т.д. То есть если надо динамически контролировать состояние кнопок тулбара, можно просто добавить макрос ON_UPDATE_COMMAND_UI. Мне это кажется достаточно естесственным.

А в Linux в Qt, видимо такого нет (или я плохо читал документацию). Приходится обновлять вручную. В Qt есть класс QAction. Это как мы абстракция. Он может быть связан как с меню, так и с кнопками тулбара. Так вот можно объекту класса QAction говорить, что соответствующая команда должна быть включена, отключена, выделена (checked).
И получается что при срабатывании какой то команды мне приходится для различных объектов QAction проставлять их состояния. Это нормально ?
Нет ли какого универсального способа делать это ? Наподобие как в MFC ?

Если нет, то как можно отследить состояние idle в программе на Qt ? Дело в том, что в диалогах MFC можно, например, обрабатывать сообщение WM_KICKIDLE и обновлять как хочется (сразу все) элементы управления. Есть ли что то подобное в линукс/Qt ?

Извиняюсь, если непонятно выразился.
« Последнее редактирование: 11 Январь 2007, 00:18:44 от aeron » Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #1 : 15 Январь 2007, 19:40:17 »

Вобщем, обо всем по порядку.
Цитировать
В Windows есть такое понятие как idle.

В линуксе оно как бы тоже "есть".
Цитировать
А в Linux в Qt, видимо такого нет (или я плохо читал документацию). Приходится обновлять вручную. В Qt есть класс QAction. Это как мы абстракция. Он может быть связан как с меню, так и с кнопками тулбара. Так вот можно объекту класса QAction говорить, что соответствующая команда должна быть включена, отключена, выделена (checked).
И получается что при срабатывании какой то команды мне приходится для различных объектов QAction проставлять их состояния. Это нормально ?

Это нормально.
Цитировать
Нет ли какого универсального способа делать это ? Наподобие как в MFC ?

В MFC своя модель обновления UI, в Qt - своя.
Кстати, в ATL/WTL что то наподобие этого - надо самому устанавливать состояния элементов управления, кнопок тулбаров, состояния пунктов меню.

Цитировать
Если нет, то как можно отследить состояние idle в программе на Qt ? Дело в том, что в диалогах MFC можно, например, обрабатывать сообщение WM_KICKIDLE и обновлять как хочется (сразу все) элементы управления. Есть ли что то подобное в линукс/Qt ?

Извиняюсь, если непонятно выразился.

Да нет, вроде понятно :)
Только вот имеет ли смысл подобная обработка idle (именно с целью обновления UI) ? Qt сильна своей концепцией слотов/сигналов/connections. Правильно соединив сигналы одних объектов с другими, можно добиться автоматического изменения состояний элементов пользовательского интерфейса в большинстве случаев.

Но, если отвечать непосредственно на Ваш вопрос, то - да, в Qt можно сделать некое подобие обработки idle. В свое время я такое реализовал, потратив некоторое время на изучение исходников Qt. Сделал для тулбаров и меню типа автообновления. Только вот я еще для себя не решил что же все-таки удобнее - обновлять интерфейс во время idle, или классическим методом.

Вобщем, обработку idle сделать достаточно просто. Для этого в приложении надо создать свой класс цикла обработки событий. В нем надо реализовать виртуальный метод processEvents и обрабатывать сигнал aboutToBlock. У меня это слудующим образом.
Определение класса своего цикла событий:
Код:
class CMainEventLoop : public QEventLoop
{
   Q_OBJECT

public:

   CMainEventLoop();
   ~CMainEventLoop();

public:
   
   virtual bool processEvents(ProcessEventsFlags flags);

protected:

   bool m_bCouldIdle;

protected slots:

   void OnAboutToBlock();

};


Реализация класса CMainEventLoop:

Код:
CMainEventLoop::CMainEventLoop()
   :    QEventLoop(NULL, "Main Event Loop")
{
   m_bCouldIdle = false;
   connect(this, SIGNAL(aboutToBlock()), this, SLOT(OnAboutToBlock()));
}

CMainEventLoop::~CMainEventLoop()
{
}

bool CMainEventLoop::processEvents(ProcessEventsFlags flags)
{
   if((flags & (AllEvents | WaitForMore)) == (AllEvents | WaitForMore))
       m_bCouldIdle = true;

   bool bResult = QEventLoop::processEvents(flags);

   m_bCouldIdle = false;

   return bResult;
}

void CMainEventLoop::OnAboutToBlock()
{
   if(m_bCouldIdle)
   {
       int nCount = 0;
       bool bIdle = true;

       while(bIdle && !hasPendingEvents())
       {
           if(!__app.OnIdle(nCount++))
               bIdle = false;
       }
   }
}


В слоте CMainEventLoop::OnAboutToBlock я просто вызываю метод OnIdle объекта приложения (у меня __app макросом глобально определен). А уже в OnIdle произвожу необходимую во время idle работу. Правда, там тоже хитро все сделано.

Самое главное - объект класса CMainEventLoop надо создавать до создание объекта приложения. У меня он создается как статический член класса объекта приложения.

Ну и еще стоит сказать, что подобная обработка idle - еще пол-дела. Обновление интерфейса - тот еще гимор. Для того, чтобы обновлять меню, тулбары мне пришлось реализовывать свои классы, производные от QAction, QPopupMenu, QToolBar, а также класс CIdleNotifier, который распространяет сигнал об idle среди объектов, которые должны обновляться. Короче, для небольших приложений, имхо, не стоит городить такое.
Записан

Aeron
Пользователь
***
Офлайн Офлайн

Сообщений: 49


Просмотр профиля
« Ответ #2 : 15 Январь 2007, 21:00:24 »

Да, много написано Улыбка
Буду разбираться.

Цитировать
Ну и еще стоит сказать, что подобная обработка idle - еще пол-дела. Обновление интерфейса - тот еще гимор. Для того, чтобы обновлять меню, тулбары мне пришлось реализовывать свои классы, производные от QAction, QPopupMenu, QToolBar, а также класс CIdleNotifier, который распространяет сигнал об idle среди объектов, которые должны обновляться. Короче, для небольших приложений, имхо, не стоит городить такое.


А что, свои классы тулбаров, меню обязательно писать ?
Мне хотя бы так пока, по простому.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!