Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: kim от Январь 09, 2006, 23:24



Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: kim от Январь 09, 2006, 23:24
Идет обработка данных - (много) - порциями. По нажатию кнопки "стоп" необходимо вывести "окно" которое возможно убрать только по определенному сигналу, который выдаст функция обработки данных. Интерфейс программы на время показа "окна" естесственно замораживается.
Пример: Есть 130 строк текста. Некоторая функция, скажем "checkString" обрабатывает  это количество строк по 5. В процессе обработки получена команда "стоп" (скажем некоторая переменная isCheck равна TRUE) - появилось данное "окно". Функция обработки данных "checkString" обнаружила, что переменна "isCheck" равна TRUE и дообработав остатки от оставшихся 5 строк выдала сигнал, скажем "stopCheck" - для того чтобы убрать вышеуказанное окно.
Вопрос: 1. Как реализовать данное "окно"? 2. Как поймать данный сигнал (stopCheck) в самом "окне" и обработав его удалить себя?


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: Steven_Orko от Январь 09, 2006, 23:53
Я делал тоже самое, когда писал прогу на лабу по моделированию диспетчеризации. Там как раз используется почти то, что ты хочешь, только процесс обработки не замораживается... В принципе, это добавить не сложно. Если хочешь, то могу отослать весь проект на мыло...


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: kim от Январь 10, 2006, 00:01
Надо так как описано: т.е. дообрабатывается что осталось и "стоп" )))
Да, конечно, вышли если не трудно.
А по теме уточнение: на данном окне не должно быть всяких кнопок и по Escape, к примеру, окно тоже убрать нельзя - только по описанному действию.
Возможно окошко QProgressDialog? Но как убрать кнопочки? (WStyle_?) Если да, то как реализовать работу по описанному алгоритму?
Вопрос остается открытым.


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: Steven_Orko от Январь 10, 2006, 00:17
Например, можно сделать окно без рамки. Если ты там собираешься показывать, что в данный момент останавливаешь операцию, то так даже смотреться будет лучше(ИМХО). Ну а закрыть окно можно, послав ему сообщение или событие - аналог сообщений в QT. Также можно вызвать метод по закрытию окна (hide), когда поток, который производит обработку, посылает специальное событие основному окну, где кнопка "стоп" находится.  В customEvent() оно обрабатывается и окно твое закрывается.
Смотри проект на почте, ща пошлю )))

добавлено спустя 5 минут:

 Все, отослал. Получай


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: kim от Январь 10, 2006, 00:49
Примерно накидал ситуацию. Но не пашет  :(
Код:

//окно процесса остановки
act_Stop *dlg_Stop;
//флаг остановки
bool isCheck=FALSE;

void MainWindow::init()
{
    ...
    connect (this, SIGNAL(checkStop()), this, SLOT(closeStopDlg()));
}

//
void MainWindow::actStop()
{
    //this dialog AS QDialog - modal
    act_Stop *dlg_Stop = new act_Stop(this, QString::Null, TRUE, Qt::WStyle_Customize|Qt::WStyle_NoBorder);
    dlg_Stop->exec();
    // OR - ?
    //dlg_Stop->show();
    //dlg_Stop->raise();
    //dlg_Stop->setActiveWindow();
    isCheck=TRUE;
}
//
void MainWindow::checkString()
{
    ...
    if (countString==0)
    if  (isCheck)
        emit checkStop();
        else
            ...//proceed working
}
//
void MainWindow::closeStopDlg()
{
    dlg_Stop->hide();
        OR
    delete dlg_Stop;

    isCheck=FALSE;
}

Как самое простое, как мне кажеться. Но хочется чтобы окошко само себя убирало. В таком случае как лучше и как послать окошку сообщение/сигнал на закрытие?
А если брать QProgressDialog - то хочется чтобы было без кнопок, чего я пока не могу добиться.


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: Steven_Orko от Январь 10, 2006, 01:22
Если под словами "без кнопок" ты имеешь ввиду верхнее системное меню, то можно поставить стиль окна Qt::FramelessWindowHint. Оно точно будет без них, так как вообще меню не будет.  По поводу флагов окнам посмотри пример examples\widgets\windowflags.
По поводу твоего окошка, чтобы оно само закрывалось, попробуй так.

В классе этого окна переопределяешь метод customEvent(). Также объявляешь свои события с наследованием QEvent. Как это делать, смотри у меня в проекте.
Для своего потока определяешь событие
Код:

enum
{
NoPartion = QEvent::User + 1,  //Событие "Обработана последняя порция"
CloseWnd                       //Событие "Закрыть окно"
};

class CNoPartionEvent : public QEvent
{
public:
  CNoPartionEvent() : QEvent((QEvent::Type) NoPartion) {};
}

class CCloseMyWnd : public QEvent
{
public:
  CCloseMyWnd() : QEvent((QEvent::Type) CloseWnd) {};
}


Дальше переопределяем приват-метод(см. Assistents) customEvent()
Код:

void MainWindow::customEvent(QEvent * event)
{
  if ((int) event->type() == NoPartion)
  {
         QApplication::postEvent(pMyDlg, new CCloseMyWnd());
         //...
   }
}

При этом pMyDlg - указатель на твое окошко, которое ты хочешь показать/убрать. По поводу статического метода postEvent() читай Assistent.
Из потока ты также посылаешь событие своему окну:
Код:

class QMyThread : public QThread
{
  //...
 protected:
  void run() //Процедура, которая обрабатывает твои строки
 {
 //...
 
 //Проверили флаг останова, он есть
 //Добоработали полученные 5 строк
 //Послали событие в главное окно
  QApplication::postEvent(pMyHeadWnd, new CCloseMyWnd());
 //...
 }
  //...
}

 //pMyHeadWnd имеет тип MainWindow*

В классе твоего диалогового окошка тоже переопределяем customEvent():
Код:

void MainWindow::customEvent(QEvent * event)
{
  if ((int) event->type() == CCloseMyWnd)
  {
         //Здесь пиши код, который закрое твое окно, как тебе надо
   }
}


Почитай Assistenta по поводу QEvent. Там в определенных случаях надо делать accept().
Вот все, что касается твоего сигнала. Впринципе, в четверке есть механизм сигнал-слот, кажется, между поток GUI и потоком не GUI. Ну, а в трехе тебе только так, ИМХО, через события. Можешь еще по этой теме почитать Бланшета. Там очень хорошо это расписано.


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


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: kim от Январь 10, 2006, 01:41
Спасибо за ответы. Как я понимаю ты не очень с QT знаком)) но тем не менее...
А что по поводу "кнопочек" - да я знаю как убрать и бордюр окна и системный заголовок окна. Я говорил, что если использовать QProgressDialog - то как в нем избавиться от стандартных кнопок. (ну и если использовать любой диалог, тоже). Соответственно убирать такие диалоги только программно в таком случае можно.
Ладно буду ковыряться, если что то будет непонятно - сделаю новый пост или здесь отпишусь)))


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: Steven_Orko от Январь 10, 2006, 01:43
Можно узнать? По каким признакам ты установил, что я знаком с Qt не очень?


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: kim от Январь 10, 2006, 02:03
..."послав ему сообщение или событие - аналог сообщений в QT"... ну и т.д. Тоесть я неправильно выразился тогда. Знаешь и QT и что-то еще и как-то это "перемешивается" ... может по таким мелочам и показалось. Если это не так - прошу прощения.


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: Steven_Orko от Январь 10, 2006, 02:07
Возможно, я смешанно объяснял, но
Цитировать
ты не очень с QT знаком
, но в этом ты ошибся ))) Желаю удачи с QProgressDialog


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: kim от Январь 10, 2006, 11:24
Твой пример, посланный по почте - очень помог.
Работает, только если QCustomEvent.
Проблема: Не могу отловить в "окошке" посланное событие (((
Окошко - модальный диалог.
Что не так может быть?


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: Steven_Orko от Январь 10, 2006, 17:04
Цитировать
Работает, только если QCustomEvent.

В смысле, работает только, если ты наследуешь от него? Вполне возможно.  
Цитировать
Проблема: Не могу отловить в "окошке" посланное событие (((
Окошко - модальный диалог.
Что не так может быть?

Возможно, ты не устанавливаешь модального результата.
С этим тебе долны помочь функции virtual void accept (), virtual void done(int r ),
virtual void reject (). Если, конечно, я правильно понял вопрос. Т.е. у тебя окно просто не закрывается, верно? Или что значит:
Цитировать
Проблема: Не могу отловить в "окошке" посланное событие (((


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: kim от Январь 13, 2006, 18:04
Все работает! Огромное спасибо за помощь!
Сейчас вот только надо додуматься как запретить окошку убираться по "Esc" :-))) А так УСЁ работает. Ну и за помощь в виде примера-проекта - отдельное спасибо.

добавлено спустя 34 минуты:

 У меня сработало так (чтобы модальный диалог не реагировал на Esc):

Код:

myDialog::keyPressEvent(QKeyEvent *event)
{
    if(event->key()!=Key_Escape) QDialog::keyPressEvent(event);
}


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: Steven_Orko от Январь 13, 2006, 18:20
А можно еще вот так(ИМХО):
Код:
void myDialog::keyPressEvent(QKeyEvent *event) 
{
    if(event->key() == Key_Escape) event->ignore();
    else  event->accept()
}


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: kim от Январь 15, 2006, 06:20
А разве
Код:

 event->ignore();

так можно!? Вроде в документации сказано, что Esc не может быть проигнорирован.

добавлено спустя 1 час 19 минут:

 В итоге получилось:
hgevent.h
Код:

#ifndef HGEVENT_H
#define HGEVENT_H

#include <qevent.h>

enum
{
  IsHaveStop=1001,  //Событие "имеем признак стоп"
  CloseProgressStop=1002  //Событие "удалить окно завершения"
};

class HaveStop : public QCustomEvent
{
  public: HaveStop() : QCustomEvent((QCustomEvent::Type) IsHaveStop) {};
};

class CloseProgressStopDlg : public QCustomEvent
{
  public: CloseProgressStopDlg() : QCustomEvent((QCustomEvent::Type) CloseProgressStop) {};
};

#endif


Код:

//mainwindow

void MainWindow::customEvent(QCustomEvent * event)
{
  if ((int) event->type() == IsHaveStop)
  {
         QApplication::postEvent(pMyDlg, new CloseProgressStopDlg());
         //...
   }
}

void MainWindow:: run() //Процедура, которая обрабатывает строки
{
  //...
 
  //Проверили флаг останова, он есть
  //Добоработали полученные 5 строк
  //Послали событие в главное окно
  QApplication::postEvent(this, new HaveStop());
  //...
}

В классе диалогового окошка тоже переопределяем customEvent():
Код:

void DlgWindow::customEvent(QCustomEvent * event)
{
  if ((int) event->type() == CloseProgressStop)
  {
    reject();
  }
}


Огромное спасибо за помощь!


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: Steven_Orko от Январь 15, 2006, 07:21
Самому числовые значения для событий лучше не писать. Для пограничного значения есть специальная костанта QEvent::User, после которой ты определяешь свои события.
Вот начало, которое лучше переделать:
Код:
#ifndef HGEVENT_H 
#define HGEVENT_H

#include <qevent.h>

enum
{
  IsHaveStop=QEvent::User + 1,  //Событие "имеем признак стоп"
  CloseProgressStop  //Событие "удалить окно завершения"
};


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: kim от Январь 15, 2006, 07:34
А ну да. Так конечно более правильно. Просто просматривая "училку" тролей нашел такой способ.  :lol: Спасибки.


Название: 3.3.4 - "Окно" которое можно убрать по сигналу?
Отправлено: Steven_Orko от Январь 15, 2006, 07:42
:D не за что