The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Qt: Проблема с фокусом ввода и перехватом нажатий клавиш"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Qt: Проблема с фокусом ввода и перехватом нажатий клавиш" 
Сообщение от sk_alex emailИскать по авторуВ закладки(??) on 09-Фев-05, 13:21  (MSK)
Доброго времени суток.

Имеется MDI-программа на Qt. MDI-окошко разделено сплиттером пополам. Верхняя часть окна - виджет, наследованный от QScrollView; нижняя - от QTextEdit (используется в ReadOnly-режиме, в конструкторе класса стоит setReadOnly (TRUE)). Верхняя часть окна перехватывает и обрабатывает нажатия на клавиатуру; от нижней требуется только отображение (от QTextEdit его наследовали только для удобства построчного добавления туда текстовой информации).

Беда: пока окошко только что открыто верхняя половина прекрасно перехватывает и обрабатывает все нужные нажатия на клавиши. Стоит только мышкой щелкнуть на нижнюю часть окна (т.е. насколько я понимаю, перемещается фокус) - верхней частью окна перестают перехватываться нажатия на Enter и стрелочки. Буквы/цифры и BackSpace перехватываются, как и раньше. По нажатию стрелочек скроллится текст в нижнем окне. Клик мышкой на верхней части окна, увы, фокус обратно не возвращает. :-(

Окна создаются следующим образом:
В классе приложения:
void BsconsApp::createClient(BsconsDoc* doc)
{
  BSConsWindowSplitter *pSplit = new BSConsWindowSplitter (pWorkspace , "main");
    
  CmdWindow* cmdWin = new CmdWindow (pSplit, 0, WDestructiveClose);
  pSplit->pCmdWin = cmdWin;
  BsconsView* logWin = new BsconsView(doc, pSplit, 0, WDestructiveClose);
  doc->addView (logWin);

  pSplit->setResizeMode(logWin, QSplitter::KeepSize);

#ifdef Q_WS_QWS
  // Qt/Embedded XOR drawing not yet implemented.
  pSplit->setOpaqueResize (TRUE);
#endif

  pSplit->resize(640, 480);
  pSplit->show();
}

BSConsWindowSplitter - класс, унаследованный от QSplitter и отличающийся от него только дополнительной парой полей (в частности, pCmdWin, в котором хранится указатель на объект виджета верхней части окна), ни один метод родителького класса там не переопределяется.
CmdWindow - класс, унаследованный от QScrollView, верхняя часть MDI-окошка
BsconsView - класс, унаследованный от QTextEdit, нижняя часть MDI-окошка.

Нажатие клавиш перехватывается через класс приложения следующим образом:
void BsconsApp::keyPressEvent (QKeyEvent *e)
{
    if (pWorkspace->windowList().isEmpty())
        return;
    else
    {
        BSConsWindowSplitter *pActiveSplitter = (BSConsWindowSplitter*)                      (pWorkspace->activeWindow());
        if (pActiveSplitter != 0)
        {
            CmdWindow *pActiveCmdWin = pActiveSplitter->pCmdWin;
            if (pActiveCmdWin != 0)
                pActiveCmdWin->OnKeyPressed (e);
        }
    }
}
т.е. определяется текущее активное MDI-окно и вызывается соответствующая функция для верхней части окна. В виджет нижней части окна по идее события нажатия на клавиатуру вообще не должны приходить. Однако приходят. :-( Как только нижняя часть окна получает фокус ввода, при нажатии на буквы/цифры все происходит по прежнему сценарию. При нажатии же на Enter или стрелочки мы в функцию BsconsApp::keyPressEvent просто не попадаем. Не понимаю, как виджет окна, унаследованного от QTextEdit перехватывает нажатия клавиш, минуя перехват клавиш на уровне класса приложения.

Надеюсь, ситуацию изложил достаточно понятно.

Если не трудно, подскажите, где тут может быть проблема? Нужно, чтобы события от клавиатуры перехватывались всегда и только верхним окном.

Заранее спасибо всем откликнувшимся.

  Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "Qt: Проблема с фокусом ввода и перехватом нажатий клавиш" 
Сообщение от MaximKuznetsov Искать по авторуВ закладки on 09-Фев-05, 21:09  (MSK)
>Доброго времени суток.
>
>Имеется MDI-программа на Qt. MDI-окошко разделено сплиттером пополам. Верхняя часть окна -
>виджет, наследованный от QScrollView; нижняя - от QTextEdit (используется в ReadOnly-режиме,
>в конструкторе класса стоит setReadOnly (TRUE)). Верхняя часть окна перехватывает и
>обрабатывает нажатия на клавиатуру; от нижней требуется только отображение (от QTextEdit
>его наследовали только для удобства построчного добавления туда текстовой информации).
>
>Беда: пока окошко только что открыто верхняя половина прекрасно перехватывает и обрабатывает
>все нужные нажатия на клавиши. Стоит только мышкой щелкнуть на нижнюю
>часть окна (т.е. насколько я понимаю, перемещается фокус) - верхней частью
>окна перестают перехватываться нажатия на Enter и стрелочки. Буквы/цифры и BackSpace
>перехватываются, как и раньше. По нажатию стрелочек скроллится текст в нижнем
>окне. Клик мышкой на верхней части окна, увы, фокус обратно не
>возвращает. :-(
>
>Окна создаются следующим образом:
>В классе приложения:
>void BsconsApp::createClient(BsconsDoc* doc)
>{
>  BSConsWindowSplitter *pSplit = new BSConsWindowSplitter (pWorkspace , "main");
>
>  CmdWindow* cmdWin = new CmdWindow (pSplit, 0, WDestructiveClose);
>  pSplit->pCmdWin = cmdWin;
>  BsconsView* logWin = new BsconsView(doc, pSplit, 0, WDestructiveClose);
>  doc->addView (logWin);
>
>  pSplit->setResizeMode(logWin, QSplitter::KeepSize);
>
>#ifdef Q_WS_QWS
>  // Qt/Embedded XOR drawing not yet implemented.
>  pSplit->setOpaqueResize (TRUE);
>#endif
>
>  pSplit->resize(640, 480);
>  pSplit->show();
>}
>
>BSConsWindowSplitter - класс, унаследованный от QSplitter и отличающийся от него только дополнительной
>парой полей (в частности, pCmdWin, в котором хранится указатель на объект
>виджета верхней части окна), ни один метод родителького класса там не
>переопределяется.
>CmdWindow - класс, унаследованный от QScrollView, верхняя часть MDI-окошка
>BsconsView - класс, унаследованный от QTextEdit, нижняя часть MDI-окошка.
>
>Нажатие клавиш перехватывается через класс приложения следующим образом:
>void BsconsApp::keyPressEvent (QKeyEvent *e)
>{
>    if (pWorkspace->windowList().isEmpty())
>        return;
>    else
>    {
>        BSConsWindowSplitter *pActiveSplitter = (BSConsWindowSplitter*)                      (pWorkspace->activeWindow());
>        if (pActiveSplitter != 0)
>
>        {
>            CmdWindow *pActiveCmdWin = pActiveSplitter->pCmdWin;
>            
>if (pActiveCmdWin != 0)
>                pActiveCmdWin->OnKeyPressed (e);
>        }
>    }
>}
>т.е. определяется текущее активное MDI-окно и вызывается соответствующая функция для верхней части
>окна. В виджет нижней части окна по идее события нажатия на
>клавиатуру вообще не должны приходить. Однако приходят. :-( Как только нижняя
>часть окна получает фокус ввода, при нажатии на буквы/цифры все происходит
>по прежнему сценарию. При нажатии же на Enter или стрелочки мы
>в функцию BsconsApp::keyPressEvent просто не попадаем. Не понимаю, как виджет окна,
>унаследованного от QTextEdit перехватывает нажатия клавиш, минуя перехват клавиш на уровне
>класса приложения.
>
>Надеюсь, ситуацию изложил достаточно понятно.
>
>Если не трудно, подскажите, где тут может быть проблема? Нужно, чтобы события
>от клавиатуры перехватывались всегда и только верхним окном.
>
>Заранее спасибо всем откликнувшимся.

setFocusPolicy(NoFocus) возможно (для нижней части)
(+вообще тщательней отнестись к этому самому policy - правильно выставить для всех виджетов; по умолчанию для Qwidget - NoFocus, а для потомков - для кого как)
или (на крайний случай) перехватать FocusInEvent и насильно передать фокус кому и куда надо..

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "Qt: Проблема с фокусом ввода и перехватом нажатий клавиш" 
Сообщение от sk_alex emailИскать по авторуВ закладки(??) on 10-Фев-05, 18:25  (MSK)
>setFocusPolicy(NoFocus) возможно (для нижней части)
>(+вообще тщательней отнестись к этому самому policy - правильно выставить для всех
>виджетов; по умолчанию для Qwidget - NoFocus, а для потомков -
>для кого как)
>или (на крайний случай) перехватать FocusInEvent и насильно передать фокус кому и
>куда надо..

Большое спасибо. Помогло.

  Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх


Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру