Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: cdsmika от Октябрь 25, 2009, 00:04



Название: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 25, 2009, 00:04
Привет!
Не найду никак сигнал в QTabWidget, срабатывающий перед переключением закладки, для разрешения или запрещения перехода. Может кто подскажет, а???


Название: Re: Событие перед переключением tab
Отправлено: lit-uriy от Октябрь 25, 2009, 02:17
для разрешения/запрещения можно делать вкладки неактивными (запрещёнными)


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 25, 2009, 11:41
для разрешения/запрещения можно делать вкладки неактивными (запрещёнными)
Ну не. История такая: На закладке QTableView, соединенный с QSqlRelationalModel. Мне нужно перед переходом на другую закладку проверять изменились ли данные и предлагать эти изменения сохранить. Юзвер может и перейти на др. закладку не сохраняя данные, а может нажать "Отмена" и вообще отменить переход. (То бишь три кнопки: "Сохранить изменения?" "Да", "Нет", "Отмена")


Название: Re: Событие перед переключением tab
Отправлено: spectre71 от Октябрь 25, 2009, 11:46
для разрешения/запрещения можно делать вкладки неактивными (запрещёнными)
Ну не. История такая: На закладке QTableView, соединенный с QSqlRelationalModel. Мне нужно перед переходом на другую закладку проверять изменились ли данные и предлагать эти изменения сохранить. Юзвер может и перейти на др. закладку не сохраняя данные, а может нажать "Отмена" и вообще отменить переход. (То бишь три кнопки: "Сохранить изменения?" "Да", "Нет", "Отмена")

Попробуй повесить фильтр событий на свой QTabWidget


Название: Re: Событие перед переключением tab
Отправлено: spectre71 от Октябрь 25, 2009, 11:53
Вернее на QTabBar у QTabWidget.
QTabBar * QTabWidget::tabBar () const


Название: Re: Событие перед переключением tab
Отправлено: f0x от Октябрь 25, 2009, 14:18
Держи в переменной индекс текущего таба и отлавливай сигнал изменения таба. Если нужно, возвращай юзера в таб с сохраненным ранее индексом.


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 25, 2009, 18:08
Держи в переменной индекс текущего таба и отлавливай сигнал изменения таба. Если нужно, возвращай юзера в таб с сохраненным ранее индексом.
Ну это ж кривизна. Этот сигнал срабатывает уже после инициализации нового таба, а это довольно долгий процесс (загрузка данных из БД). Почему в Qt события не подразделяются на до и после?


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 25, 2009, 18:12
Вернее на QTabBar у QTabWidget.
QTabBar * QTabWidget::tabBar () const

error: `QTabBar* QTabWidget::tabBar() const' is protected


Название: Re: Событие перед переключением tab
Отправлено: f0x от Октябрь 25, 2009, 18:18
Ну это ж кривизна. Этот сигнал срабатывает уже после инициализации нового таба,
а по какому событию у тебя инициализация? неужели нельзя сделать сначала проверку, а потом инициализировать если надо? А если не надо, вернуть юзера назад. По-моему все достаточно просто...


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 25, 2009, 18:24
Ну это ж кривизна. Этот сигнал срабатывает уже после инициализации нового таба,
а по какому событию у тебя инициализация? неужели нельзя сделать сначала проверку, а потом инициализировать если надо? А если не надо, вернуть юзера назад. По-моему все достаточно просто...
попробую


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 25, 2009, 18:30
Ну это ж кривизна. Этот сигнал срабатывает уже после инициализации нового таба,
а по какому событию у тебя инициализация? неужели нельзя сделать сначала проверку, а потом инициализировать если надо? А если не надо, вернуть юзера назад. По-моему все достаточно просто...

Кстати при таком раскладе виден переход на следующую закладку, после которого задается вопрос, а потом видна отмена - не есть гуд.


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 25, 2009, 18:32
Вернее на QTabBar у QTabWidget.
QTabBar * QTabWidget::tabBar () const

Есть пример использования?


Название: Re: Событие перед переключением tab
Отправлено: kirill от Октябрь 26, 2009, 06:18
Вернее на QTabBar у QTabWidget.
QTabBar * QTabWidget::tabBar () const

Есть пример использования?

Раз протектед то наследуйся от QTabWidget


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 26, 2009, 11:45
Вернее на QTabBar у QTabWidget.
QTabBar * QTabWidget::tabBar () const

Есть пример использования?

Раз протектед то наследуйся от QTabWidget
То бишь для реализации такой простой штуки мне нада еще и табвиджет переопределять?
Блин, короче понял одну истину - надо было все классы Qt наследовать перед тем как писать проект  :(


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 28, 2009, 09:18
Вернее на QTabBar у QTabWidget.
QTabBar * QTabWidget::tabBar () const

Есть пример использования?

Раз протектед то наследуйся от QTabWidget
Тогда в чем смысл installEventFilter, если можно все события перехватывать в наследнике?


Название: Re: Событие перед переключением tab
Отправлено: Igors от Октябрь 28, 2009, 14:41
Кстати при таком раскладе виден переход на следующую закладку, после которого задается вопрос, а потом видна отмена - не есть гуд.
Ничего лучшего не видно, может быть попробовать замаскировать это с помощью setUpdateEnabled.
Впечатление такое что Вы "гладите кошку против шерсти" - табы предполагают безмодальное поведение которое Вы упорно хотите превратить в модальное. Вместо этого чем плохо например приделать к контролам валидаторы? Писать не больше


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 28, 2009, 15:01
Кстати при таком раскладе виден переход на следующую закладку, после которого задается вопрос, а потом видна отмена - не есть гуд.
Ничего лучшего не видно, может быть попробовать замаскировать это с помощью setUpdateEnabled.
Впечатление такое что Вы "гладите кошку против шерсти" - табы предполагают безмодальное поведение которое Вы упорно хотите превратить в модальное. Вместо этого чем плохо например приделать к контролам валидаторы? Писать не больше
Да, я тоже думаю об использовании setUpdateEnabled, но еще не пробовал.
впечатление может и правильное, но я не могу иначе. При переключении закладок необходимо перезагружать данные из БД. А если перезагружать, то естественно необходимо спросить у человека не хочет ли он потерять свои изменения. Не понял как валидаторы здесь могут помочь. Как я понял из хелпа валидаторы можно установить только на QLineEdit и QComboBox. У меня QTableWidget (но это не обязательно, может быть и любой другой класс, в том числе и свой компонент)


Название: Re: Событие перед переключением tab
Отправлено: Авварон от Октябрь 28, 2009, 15:07
естественно необходимо спросить у человека не хочет ли он потерять свои изменения.
совсем не естественно. я бы переработал интерфейс...


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 28, 2009, 15:11
естественно необходимо спросить у человека не хочет ли он потерять свои изменения.
совсем не естественно. я бы переработал интерфейс...
Хорошо, научи меня как


Название: Re: Событие перед переключением tab
Отправлено: Авварон от Октябрь 28, 2009, 15:15
что находится внутри табов? можно скриншотик? Что пользователь делает - каким образом он редактирует бд? Почему нельзя делать сабмит в бд по ходу редактирования?


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 28, 2009, 15:20
что находится внутри табов? можно скриншотик? Что пользователь делает - каким образом он редактирует бд? Почему нельзя делать сабмит в бд по ходу редактирования?
Что находится внутри табов - см. выше. Скриншотик сделаю. Пользователь делает все мыслимые и не мыслимые манипуляции с данными (добавление, удаление, изменение, привязка связанных данных, фоток, изменяет структуру данных в БД и т.д.). Нельзя, т.к. в этом случае изменения нельзя будет откатить (как пошагово так и полностью).


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 30, 2009, 02:22
что находится внутри табов? можно скриншотик? Что пользователь делает - каким образом он редактирует бд? Почему нельзя делать сабмит в бд по ходу редактирования?
Вот скриншот


Название: Re: Событие перед переключением tab
Отправлено: Igors от Октябрь 30, 2009, 11:16
Зачем нужны табы если Вы "Исходящие документы" уже показали выше 2 раза (более чем ясно)  :)


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 30, 2009, 12:12
Зачем нужны табы если Вы "Исходящие документы" уже показали выше 2 раза (более чем ясно)  :)
А это меняет дело? Просто дублирую для пользователей. Тулбар можно скрыть при желании


Название: Re: Событие перед переключением tab
Отправлено: Igors от Октябрь 30, 2009, 13:00
А это меняет дело? Просто дублирую для пользователей. Тулбар можно скрыть при желании
Так и дублируйте тулбаром или просто лайаутом с набором кнопок/чекбоксов. Табы-то привлекать зачем?


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 30, 2009, 13:07
А это меняет дело? Просто дублирую для пользователей. Тулбар можно скрыть при желании
Так и дублируйте тулбаром или просто лайаутом с набором кнопок/чекбоксов. Табы-то привлекать зачем?
Затем, чтобы отображать сложный интерфейс (не только TableWidget) и переключать задачи (проблема в том, что задачи могут быть разной структуры, т.е. документы, пользователи и т.д. При этом необходимо перезагружать данные из БД) можно было просто указанием индекса таба. А зачем по-вашему компонент QTabWidget?


Название: Re: Событие перед переключением tab
Отправлено: Igors от Октябрь 30, 2009, 13:50
Затем, чтобы отображать сложный интерфейс (не только TableWidget) и переключать задачи (проблема в том, что задачи могут быть разной структуры, т.е. документы, пользователи и т.д. При этом необходимо перезагружать данные из БД) можно было просто указанием индекса таба. А зачем по-вашему компонент QTabWidget?
Если нужно "сменить страницу по индексу" то QStackedLayout должен подойти. Конечно, трудности с  QTabWidget невеликие и победить их можно, но табы провоцируют пользователя "везде полазить" что здесь не очень Вам нужно


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 30, 2009, 18:41
Затем, чтобы отображать сложный интерфейс (не только TableWidget) и переключать задачи (проблема в том, что задачи могут быть разной структуры, т.е. документы, пользователи и т.д. При этом необходимо перезагружать данные из БД) можно было просто указанием индекса таба. А зачем по-вашему компонент QTabWidget?
Если нужно "сменить страницу по индексу" то QStackedLayout должен подойти. Конечно, трудности с  QTabWidget невеликие и победить их можно, но табы провоцируют пользователя "везде полазить" что здесь не очень Вам нужно
Поясните как использование QStackedLayout может решить проблему проверки перед сменой задачи? QStackedLayout также как и QTabWidget не содержит вышеуказанного события...


Название: Re: Событие перед переключением tab
Отправлено: Igors от Октябрь 30, 2009, 18:52
Поясните как использование QStackedLayout может решить проблему проверки перед сменой задачи? QStackedLayout также как и QTabWidget не содержит вышеуказанного события...
Событие Вы возьмете от тулбара или набора кнопок. А в обработчике решите нужно ли делать setCurrentIndex для этого лайаута или заставить пользователя закончить все дела на текущей странице


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 30, 2009, 19:12
Поясните как использование QStackedLayout может решить проблему проверки перед сменой задачи? QStackedLayout также как и QTabWidget не содержит вышеуказанного события...
Событие Вы возьмете от тулбара или набора кнопок. А в обработчике решите нужно ли делать setCurrentIndex для этого лайаута или заставить пользователя закончить все дела на текущей странице
Спасибо, это конечно вариант, но есть одно НО. Тулбар задач занимает определенное место на экране, если пользователь решит его скрыть (это в принципе разрешено и без моего ведома), то не сможет переключать задачи. Значит нужно сделать фиксированные кнопки или как-то закрепить тулбар.
Таким образом, делаем вывод: для того, чтобы выдавать разрешение на смену текущего фрейма мне нужно ограничить использование интерфейса, вместо того, чтобы просто использовать событие перед переключением (такое событие в тулбаре есть во всех средах разработки, акромя Qt).
Просто пока я не нахожу единомышленников, считающих, что данный сигнал нужен и нужен он практически в каждом контейнере, позволяющем переключение фрэймов.


Название: Re: Событие перед переключением tab
Отправлено: BRE от Октябрь 30, 2009, 19:25
Таким образом, делаем вывод: для того, чтобы выдавать разрешение на смену текущего фрейма мне нужно ограничить использование интерфейса, вместо того, чтобы просто использовать событие перед переключением (такое событие в тулбаре есть во всех средах разработки, акромя Qt).
Просто пока я не нахожу единомышленников, считающих, что данный сигнал нужен и нужен он практически в каждом контейнере, позволяющем переключение фрэймов.
Так может сделать самому?
QTabBar + QStackedWidget.
Можно добавить всяких сигналов: до, в процессе и после переключения.
Это если нужно...  ;)


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 30, 2009, 19:30
Таким образом, делаем вывод: для того, чтобы выдавать разрешение на смену текущего фрейма мне нужно ограничить использование интерфейса, вместо того, чтобы просто использовать событие перед переключением (такое событие в тулбаре есть во всех средах разработки, акромя Qt).
Просто пока я не нахожу единомышленников, считающих, что данный сигнал нужен и нужен он практически в каждом контейнере, позволяющем переключение фрэймов.
Так может сделать самому?
QTabBar + QStackedWidget.
Можно добавить всяких сигналов: до, в процессе и после переключения.
Это если нужно...  ;)
Можно и так. Только тогда придется переписывать практически весь QTabWidget. QStackedWidget совсем уж пустой.
Эх, так не хотелось как и в Qt3 все стандартные классы переопределять из-за тривиальных задач...


Название: Re: Событие перед переключением tab
Отправлено: BRE от Октябрь 30, 2009, 19:32
Можно и так. Только тогда придется переписывать практически весь QTabWidget. QStackedWidget совсем уж пустой.
Эх, так не хотелось как и в Qt3 все стандартные классы переопределять из-за тривиальных задач...
Можно попробовать сделать свой TabBar с нужным функционалом и устанавливать его в готовый QTabWidget.


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 30, 2009, 19:35
Можно и так. Только тогда придется переписывать практически весь QTabWidget. QStackedWidget совсем уж пустой.
Эх, так не хотелось как и в Qt3 все стандартные классы переопределять из-за тривиальных задач...
Можно попробовать сделать свой TabBar с нужным функционалом и устанавливать его в готовый QTabWidget.
Попробую


Название: Re: Событие перед переключением tab
Отправлено: SABROG от Октябрь 30, 2009, 21:26
Держи в переменной индекс текущего таба и отлавливай сигнал изменения таба. Если нужно, возвращай юзера в таб с сохраненным ранее индексом.
Ну это ж кривизна. Этот сигнал срабатывает уже после инициализации нового таба, а это довольно долгий процесс (загрузка данных из БД). Почему в Qt события не подразделяются на до и после?

Из всего предложенного это самый логичный и простой вариант. К тому же я не помню такого, чтобы Qt чего-то сама пыталсь из БД загрузить по смене вкладки. Скорее всего это твой код и его можно переписать таким образом, чтобы загрузка происходила только при удовлетворительном условии. Если действительно присутствует факт того,что модель пытается обращаться к БД из-за того, что виджет стал видимым и работает перерисовка, то можно воспользоваться методом setUpdatesEnabled для всего виджета вкладки. В общем варианты есть.

Кстати можно поголосовать (vote) за внедрение этой фичи, раз уж тролли не против, тут (http://bugreports.qt.nokia.com/browse/QTBUG-3492)


Название: Re: Событие перед переключением tab
Отправлено: cdsmika от Октябрь 31, 2009, 10:43
Держи в переменной индекс текущего таба и отлавливай сигнал изменения таба. Если нужно, возвращай юзера в таб с сохраненным ранее индексом.
Ну это ж кривизна. Этот сигнал срабатывает уже после инициализации нового таба, а это довольно долгий процесс (загрузка данных из БД). Почему в Qt события не подразделяются на до и после?

Из всего предложенного это самый логичный и простой вариант. К тому же я не помню такого, чтобы Qt чего-то сама пыталсь из БД загрузить по смене вкладки. Скорее всего это твой код и его можно переписать таким образом, чтобы загрузка происходила только при удовлетворительном условии. Если действительно присутствует факт того,что модель пытается обращаться к БД из-за того, что виджет стал видимым и работает перерисовка, то можно воспользоваться методом setUpdatesEnabled для всего виджета вкладки. В общем варианты есть.

Кстати можно поголосовать (vote) за внедрение этой фичи, раз уж тролли не против, тут (http://bugreports.qt.nokia.com/browse/QTBUG-3492)
Код то мой. Загрузка осуществляется в том же обработчике onCurrentChanged(), но он срабатывает уже после смены. Сама модель естественно ничего не запрашивает при прорисовке виджета.
Фичу постил уже месяц назад троллям, но пока они отмалчиваются.


Название: Re: Событие перед переключением tab
Отправлено: SABROG от Октябрь 31, 2009, 13:01
но он срабатывает уже после смены.

Ну и пусть срабатывает, ты главное сохраняй при загрузке формы текущую выбранную вкладку куда-нибудь и обновляй переменную при любой смене вкладки уже после того как ты позволишь сменить её на новую. Тут же смысл в том, чтобы вернуть пользователя на предыдущую вкладку с которой он пришел на новую, а currentIndex() и index в currentChanged будут равны. Визуально пользователь будет видеть смену вкладки на новую и обратно.