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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Нет фокуса на элементе внутри QStackedWidget при запуске  (Прочитано 6963 раз)
Sasha
Гость
« : Декабрь 03, 2013, 17:00 »

Здравствуйте,

1) Создаю в дизайнере главное окно
2) Кладу в него QStackedWidget
3) Кладу в первую вкладку QStackedWidget-а LineEdit
4) Запускаю "предварительный просмотр" (Ctrl+R)

И фокуса в LineEdit-е НЕТ. Почему? И как заставить его появлятся при запуске?
Если нажать пару раз "tab" или кликнуть по LineEdit-у мышкой, то фокус появляется в нём, и после этого корректно восстанавливается в нём же, если переключиться на другую вкладку (при её наличии) и обратно.

И ещё я не могу понять как работает setFocus для виджета у которого есть дочерние виджеты. Производится ли попытка установить фокус в одном из них? Если нет, то как, имея указатель на родительский виджет, установить фокус в том дочернем виджете, который имел этот фокус последним?
« Последнее редактирование: Декабрь 03, 2013, 17:39 от Sasha » Записан
ammaximus
Гость
« Ответ #1 : Декабрь 03, 2013, 20:09 »

Если ты делаешь предпросмотр формы (Alt+Shift+R), то фокус будет появляться не сразу, т.к. там не реализуется полная логика, оно и не нужно. Если ты запустишь приложение, в котором эта форма, то фокус обязательно установится на этот элемент (если он один или отмечен как первый).

При старте фокус устанавливается на элемент виджета 1 (порядок можно поменять в дизайнере нажав F4). Если за время работы фокус поменялся на элемент Х, то этот элемент запоминается, при возвращении фокуса родителя на него и устанавливается.

Попробуй создай форму, в ней несколько лайнэдитов, щелкай за пределы приложения, а потом обратно. setFocus - работает также.

Короче, то что ты хочешь работает из коробки.
Записан
Sasha
Гость
« Ответ #2 : Декабрь 03, 2013, 21:42 »

Да, действительно, скомпилировал, запустил и фокус появился в LineEdit-е, просто у меня проблемма с этим фокусом в большом проекте и я решил сделать тест и первое, где проявилась потеря фокуса - это прям в дизайнере, о чём и написал, а создавать проект не стал.

НО!!!
Я всё-равно добился пропадания фокуса при старте программы, правда немного с другим интерфейсом:
1) Создаю в дизайнере главное окно
2) Кладу в него QTabWidget
3) первую вкладку оставляю пустой
4) Кладу во вторую вкладку LineEdit
5) Делаю активной 1-ю вкладку
6) Устанавливаю для QTabWidget политику фокуса в NoFocus (иначе LineEdit не получает фокус при старте даже располагаясь на 1-ой вкладке, что, кстати, тоже, по-моему, не верно тем более, что кнопка вкладки не подсвечивается пунктиром, хотя именно на ней фокус)
7) Запускаю (вижу первую пустую вкладку)
Крутой Кликаю мышкой по второй вкладке
9) Появляется LineEdit, НО без фокуса.

Что здесь не так?
Записан
Bepec
Гость
« Ответ #3 : Декабрь 03, 2013, 23:09 »

Это называется горе от ума Улыбающийся

Совершенно корректное и нормальное поведение виджетов. Активным является центральный виджет вкладки. И, как ни странно, это логично Улыбающийся
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #4 : Декабрь 04, 2013, 00:11 »

Если так хочется, указываете программно какому виджету нужно иметь фокус и все Улыбающийся
Записан

Sasha
Гость
« Ответ #5 : Декабрь 04, 2013, 15:02 »

Это называется горе от ума Улыбающийся

Совершенно корректное и нормальное поведение виджетов. Активным является центральный виджет вкладки. И, как ни странно, это логично Улыбающийся
Может быть...
Даже не знаю как вопросы задать, будет слишком длинно. Если кратко, то попробуйте сами сделать как я написал выше и поиграйтесь с фокусом. Всё ли Вас будет устраивать. Я исхожу из того, что, перемещаясь по вкладкам, пользователь хочет видеть фокус в каком либо виджете ВНУТРИ вкладки.

Мне кажутся не логичными следующие вещи:
ситуация1:
У TabWidget-а политика фокуса - NoFocus
В этом случае, если при старте активна вкладка на которой НИЧЕГО НЕТ, то:
1) Никакими клавиатурными комбинациями (Ctrl+Tab, Tab, стрелки) невозможно переключить вкладку, только мышью
2) После переключения мышью на вкладку с edit-ом, фокус всёравно неизвестно где. Ни в edit-е, ни на закладках, т.к. курсор не мигает и Ctrl+Tab по-прежнему не работает и стрелочки тоже, однако Tab уже срабатывает и переключает фокус в edit, после чего начинает работать и Ctrl+Tab
Т.е. вывод один - нельзя чтобы ПРИ СТАРТЕ была открыта ПУСТАЯ вкладка.
ситуация2:
У TabWidget-а политика фокуса по умолчанию - TabFocus
В этом случае, на мой взгляд вообще всё плохо:
1) Если при старте активна ПУСТАЯ вкладка, то Tab, Ctrl+Tab и даже стрелочки работают, но
1.1) почему если стрелочки переключают вкладки, то на самих кнопках-вкладках НЕ ОТОБРАЖАЕТСЯ ПУНКТИР, говорящий о фокусе? Допустим, потому, что фокус всё-же на центральном (пустом) виджете (кстати, то, что после нажатия клавиши "Tab" пунктир появляется, косвенно подтверждает это). Но почему тогда:
2) Если при старте активна НЕ пустая вкладка, например с edit-ом, то фокуса нет на edit-е, а Ctrl+Tab и стрелочки переключают вкладки и опять же БЕЗ ПОДСВЕТКИ пунктиром. Стоит нажать Tab и edit получает фокус, что теперь косвенно говорит о том, что фокус всё-же был именно на кнопках-вкладках.
И как вообще в ситуации2 действовать при старте ДАЖЕ при НЕ ПУСТОЙ вкладки, ведь по-моему логично, чтобы фокус при старте был сразу на первом редактируемом поле вкладки. Я вижу следующие выходы:
1) Делать NoFocus для TabWidget-а и иметь проблемму1 и, кроме того, не иметь возможности перейти Tab-ом на кнопки-закладок
2) Вручную перемещать фокус, но для этого нужно знать или как-то искать первый виджет, могущий получать фокус для каждой вкладки.
3) В дизайнере установить позицию табуляции TabWidget-а после всех первых элементов всех закладок, но это если и TabWidget и закладки рисуются в дизайнере одним объектом, а если каждая вкладка рисуется отдельно (и оформлена отдельным классом) и потом они все объединяются програмно в TabWidget или StackedWidget. Это я к тому, что taborder по умолчанию выстанвляется не совсем логично (или я просто не знаю как это умолчание изменить, например каким-нибудь флажком) и чтоб выправить, в общем случае нужен не особенно очевидный код. Я вроде-бы его написал, но не факт что он полностью верен (прокси фокус я даже не пытался учитывать). К тому-же, даже, если всё в одном объекте и настроен taborder, то старт с пустой вкладкой возвращает к ситуации1.
Записан
Sasha
Гость
« Ответ #6 : Декабрь 04, 2013, 15:26 »

Если так хочется, указываете программно какому виджету нужно иметь фокус и все Улыбающийся
Это вроде-бы очевидно, но не всегда в сложных случаях просто делается. Нужно, либо для каждой вкладки отлавливать событие show и там устанавливать фокус на первый элемент (а если пользователь уже был на этой вкладке и сместил фокус на другой элемент, затем сменил вкладки и вернулся? значит ещё и запоминать фокусный элемент скажем по событию hide? и так для каждой вкладки?), либо писать код поиска фокусного элемента.
Кстати приведу такой код, может кому-то пригодится или кто-то его подправит:
Код
C++ (Qt)
void MainWindow::setFocusWidget( QWidget *pw_ )
{
   QWidget *pw = pw_;
   QWidget *pwf = QApplication::focusWidget();
   if( pw==pwf || pw->isAncestorOf( pwf ) )
       return;
 
   // считаем, что если политика фокуса не имеет типа Qt::TabFocus, то такой виджет не подходит
   while( pw!=NULL && (pw->focusPolicy() & Qt::TabFocus) != Qt::TabFocus )
       pw = pw->focusWidget();
 
   if( pw==NULL )
     {
       pw = pw_;
       // считаем, что если политика фокуса не имеет типа Qt::TabFocus, то такой виджет не подходит
       while( pw->isVisible()==false || (pw->focusPolicy() & Qt::TabFocus) != Qt::TabFocus )
           pw = pw->nextInFocusChain();
     }
 
   // это нужно, если ф-я используется НЕ в момент получения события show, а как слот на сигнал currentChanged из StackedWidget-а
   QTimer::singleShot( 1, pw, SLOT(setFocus()) );
}
 
Этой ф-ии можно передать указатель на виджет, который сам не может иметь фокус, но имеет дочерние элементы, которые уже могут иметь фокус.
Сам я вначале стал использовать этот код, но потом:
1) отказался от пустой стартовой вкладки
2) сменил политику фокуса внутренних TabWidget-ов на NoFocus
3) сменил политику фокуса на NoFocus ещё нескольких элементов, находящихся на одном уровне с главным StackedWidget-ом иначе они при старте перетягивали фокус на себя.
Это позволило отказаться от этой ф-ии и пока этого хватает
« Последнее редактирование: Декабрь 10, 2013, 11:26 от Sasha » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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