Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: skaz54 от Апрель 17, 2011, 13:30



Название: Прием пользовательских сообщений
Отправлено: skaz54 от Апрель 17, 2011, 13:30
Здравствуйте.

Программа на С++ с использованием QT 4.7. Пока работает под Windows.

В программе я вызываю библиотечную функцию, в которую в качестве параметра передаю дескриптор окна.
При работе библиотечная функция посылает этому окну пользовательское сообщение.

Каким образом я могу принять это сообщение в окне и обработать его?

Использование Event и customEvent в окне, которое должно принять сообщение, успеха не принесло.

Спасибо.


Название: Re: Прием пользовательских сообщений
Отправлено: blood_shadow от Апрель 17, 2011, 14:16
Здравствуйте.

Программа на С++ с использованием QT 4.7. Пока работает под Windows.

В программе я вызываю библиотечную функцию, в которую в качестве параметра передаю дескриптор окна.
При работе библиотечная функция посылает этому окну пользовательское сообщение.

Каким образом я могу принять это сообщение в окне и обработать его?

Использование Event и customEvent в окне, которое должно принять сообщение, успеха не принесло.

Спасибо.
installEventFilter() для окна пробовал?


Название: Re: Прием пользовательских сообщений
Отправлено: skaz54 от Апрель 17, 2011, 17:18
Сейчас попробовал.
Эффекта нет.


Название: Re: Прием пользовательских сообщений
Отправлено: blood_shadow от Апрель 17, 2011, 17:19
Сейчас попробовал.
Эффекта нет.

тогда код в студию


Название: Re: Прием пользовательских сообщений
Отправлено: skaz54 от Апрель 17, 2011, 18:49
Вот код:

Сначала заголовочный файл:

..............................................................
class hwnMessage : public QObject
{
    Q_OBJECT

protected:
    bool eventFilter(QObject *obj, QEvent *event);
};

class dlg_AtlasCre : public QDialog
{
    Q_OBJECT

public:
    explicit dlg_AtlasCre(QWidget *parent = 0);
    ~dlg_AtlasCre();
    bool event(QEvent * event);
    void customevent(QEvent * event);

public slots:
    void close();
    void CreateClick();
    void HelpClick();
    void UpdateBtns();

private:
    xmlMapsDB * MapsDB;

    QLabel * Label1;
    QTableWidget * Regions;
    QLabel * Label2;
    QTableWidget * WorkArea;
    QPushButton * CreateBtn;
    QPushButton * HelpBtn;
    QPushButton * CloseBtn;
    QLineEdit * LE;
    QProgressBar * PB;
    QFileInfoList listSxf;

    void closeEvent(QCloseEvent *event);

};
#endif // DLG_ATLASCRE_H

Теперь реализация в части касающейся:

dlg_AtlasCre::dlg_AtlasCre(QWidget *parent) : QDialog(parent)
{
.......................................................
   //Это регистрация пользовательского сообщения 0х585
    int n1413 = QEvent::registerEventType(1413);
    qDebug() <<  "13=" <<n1413;
  //установка фильтра
    hwnMessage * hw = new hwnMessage();
    this->installEventFilter(hw); 
........................................................................
}

//фильтр сообщений
bool hwnMessage::eventFilter(QObject *obj, QEvent *event)
{
  qDebug() << "hwnMessage::eventFilter" << event->type();
  return QObject::eventFilter(obj, event);
}

//прием своих сообщений
bool dlg_AtlasCre::event(QEvent * event)
{
    qDebug() << "event=" << event->type();
    QDialog::event(event);
}

//прием своих сообщений
void dlg_AtlasCre::customevent(QEvent * event)
{
    qDebug() << "customevent=" << event->type();
    dlg_AtlasCre::customevent(event);
}

void dlg_AtlasCre::CreateClick()
{
............................................
//вызов функции из библиотеки, в качестве одного из параметров передаю дескриптор этого окна
//в процессе работы функции она шлет сообщения с идентификатором 0х585 в окно с переданным дескриптором
            qDebug() << "winId =" << this->winId();
            long int res = LoadDirToMap(str1.constData(), str2.constData(), (long int)this->winId());// (MSGHANDLER)MessageHandler_LoadDir);
.........................................................
}

в customEvent сообщения вообще не приходят
в event и в фильтр сообщения приходят, но не то которое нужно

Далее - отладочная информация на консоли
winId = 0x53039c  - идентификатор окна
hwnMessage::eventFilter 68
event= 68
hwnMessage::eventFilter 71
event= 71
hwnMessage::eventFilter 71
event= 71
hwnMessage::eventFilter 71
event= 71
hwnMessage::eventFilter 71
event= 71
hwnMessage::eventFilter 67
event= 67
hwnMessage::eventFilter 77
event= 77
hwnMessage::eventFilter 12
event= 12
hwnMessage::eventFilter 173
event= 173
hwnMessage::eventFilter 10
event= 10
hwnMessage::eventFilter 77
event= 77
hwnMessage::eventFilter 12
event= 12
hwnMessage::eventFilter 11
event= 11
hwnMessage::eventFilter 173
event= 173
hwnMessage::eventFilter 77
event= 77
hwnMessage::eventFilter 12
event= 12
hwnMessage::eventFilter 25
event= 25
hwnMessage::eventFilter 99
event= 99
hwnMessage::eventFilter 77
event= 77
hwnMessage::eventFilter 12
event= 12
hwnMessage::eventFilter 12
event= 12

Отправку сообщений и идентификатор окна проверил с помощью SpyXX - все соответсвует


Название: Re: Прием пользовательских сообщений
Отправлено: blood_shadow от Апрель 17, 2011, 19:50
а не проще иммитировать сигнал с заданным сообщением в LoadDirToMap
и его подключить к слоту окна в котором осуществлять обработку этого сообщения?


Название: Re: Прием пользовательских сообщений
Отправлено: skaz54 от Апрель 17, 2011, 21:29
Нет.
Эта функция из библиотеки стороннего разработчика.
Поэтому ее функционал надо принимать так как есть.

Вообще-то, как мне думается, это должен быть стандартным вопросом для Windows.

В Windows все основано на передаче и приеме сообщений от мыши, клавиатуры, другого окна и т.д.
Qt при работе в Windows должна принимать и передавать эти сообщения сообщения.

Как мне кажется, для отправки сообщения можно использовать функции sendEvent и postEvent.
А где они принимаются?

Я в Qt новичок., поэтому этот вопрос.





Название: Re: Прием пользовательских сообщений
Отправлено: blood_shadow от Апрель 17, 2011, 21:51
честно говоря сам такого ниразу не делал, нарыл в ассистанте ф-ции:
bool QCoreApplication::sendEvent ( QObject * receiver, QEvent * event ) и
void QCoreApplication::postEvent ( QObject * receiver, QEvent * event )
посмотри их может это то что тебе нужно


Название: Re: Прием пользовательских сообщений
Отправлено: Drafter от Апрель 18, 2011, 11:03
Все правильно, следует использовать postEvent или sendEvent (желательно сделать свой класс сообщения, унаследовавшись от QEvent).
А принимать сообщения логичней всего в виртуальном методе окна-получателя: customEvent(QEvent *event).

P.S. Обратите внимание, в коде, который Вы привели, customevent - написано маленькими буквами, т.е. Вы создали свой метод, вместо того, чтобы перегрузить виртуальный customEvent. Видимо, поэтому туда ничего и не приходит (кстати, у Вас в этой функции - бесконечная рекурсия запускается ко всему прочему :)).

P.P.S. Вообще же, учитывая специфику Вашей задачи, лучше всего смотреть в сторону:
bool QWidget::winEvent (MSG* message, long* result); [virtual]
bool QCoreApplication::winEventFilter ( MSG* msg, long* result); [virtual]

Правда, работать они будут - исключительно под Windows.



Название: Re: Прием пользовательских сообщений
Отправлено: skaz54 от Апрель 18, 2011, 12:59
Большое спасибо Drafter.

Именно то, что мне и надо.

Использую функцию
bool QWidget::winEvent ( MSG * message, long * result )   [virtual protected]

Все замечания по тексту так же оказались правильные.

Еще раз спасибо.