Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Авварон от Сентябрь 20, 2011, 21:26



Название: Пересечение эдит тригеров с экшном
Отправлено: Авварон от Сентябрь 20, 2011, 21:26
Дано, виджет со слотом:
Код:
void FileManagerWidget::rename()
{
    Q_D(FileManagerWidget);

    QModelIndexList indexes = d->selectedIndexes();
    if (indexes.count() != 1) {
//        emit error();
    } else {
        d->currentView->edit(indexes.first());
    }
}

Экшн:
Код:
    m_widget = new FileManagerWidget();
    QAction* act = new QAction(tr("Rename"), this);
    act->setShortcut(tr("Return"));
    act->setShortcutContext(Qt::WidgetShortcut);
    container()->addAction(act);
    m_widget->addAction(act);
    connect(act, SIGNAL(triggered()), m_widget, SLOT(rename()));

У виджета стоит фокус прокси на d->currentView. Посему проблема - я не могу закончить редактирование привычным нажатием Ретурна - его перехватывает экшн. Если экшн класть на парента виджета, ничего не работает (оно и понятно, у него фокуса нет), если деать Qt::WindowShortcut, то пересечение с аналогичным экшном в менюшке.

Беда:(


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: asvil от Сентябрь 20, 2011, 22:48
беда. не зачем так с виджетами извращаться. вашему пользователю что надо, редактировать. Так скажите ему чтобы эфдва нажимал. И вообще эфдва общепринятый шорткат для редактирования ячеек таблиц. А ви ему ентер хотите захардкодить. нехорошо.


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: Авварон от Сентябрь 20, 2011, 22:52
Вы на маке не работали?

Хорошо, на винде у меня повешен на Return открытие файла - тоже прикажете переделать? В момент нажатия Return'а редактирование конечно прекращается, путем открытия файла.


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: asvil от Сентябрь 20, 2011, 23:04
согласен qkeysequence не содержит edit.
экшн на вью не вешайте и в слоте экшена делайте вью-edit(вью-currentIndex());


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: Авварон от Сентябрь 20, 2011, 23:16
Не могу я не вешать экшн на виджет, тк необходимо, чтобы он был привязан к виджету. Ладно, я убрал шорткат у этого экшна, оставил только у экшна в меню. Проблема что на маке по-прежнему триггерится тот экшн, к-ый в меню и перекрывает редактирование.


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: Авварон от Сентябрь 20, 2011, 23:42
Поправка - на линухе то же поведение - при нажатии энтера файл открывается (триггерится экшн в меню, а не должно бы)


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: asvil от Сентябрь 21, 2011, 09:54
жертвуйте шоркатом, тем более что ентер таки не для шорткатов придуман.


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: Авварон от Сентябрь 21, 2011, 12:11
Открытие фалов в винде делается Ретурном. Не могу.
На маке пожертвовал; использую шорткат самой вьюхи, но что с виндой делать?


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: kambala от Сентябрь 21, 2011, 12:27
может на маке сделать открытие тоже ретурном, а переименование - энтером? так, например, реализовано в Path Finder.


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: asvil от Сентябрь 21, 2011, 12:32
я правильно понял, вы хотите чтобы у сущности вью поведение на ретурн зависило от редактировани/нередактирование.
значит поведение ретурн должно быть реализовано во вью. наследование и переопределение keypress(event).
далее вы хотите чтобы в приложении был экшн который бы открывал файл выделенный во вью.
значит слот экшна должен открывать файл(вью->currentIndex()).
Кроме того я услышал, что у вас есть экшны и в меню. Это некорректно, экшн такая сущность которая должна пристуствовать в одном экземпляре.

Так делать некорректно.
Код:
    QModelIndexList indexes = d->selectedIndexes();
    if (indexes.count() != 1) {
//        emit error();
    } else {
        d->currentView->edit(indexes.first());

Надо так:
Код:
        d->currentView->edit(d->currentView->currentIndex());


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: asvil от Сентябрь 21, 2011, 12:33
может на маке сделать открытие тоже ретурном, а переименование - энтером? так, например, реализовано в Path Finder.
стоп. ретурн и ентер разве не одна кнопка?


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: Пантер от Сентябрь 21, 2011, 13:06
стоп. ретурн и ентер разве не одна кнопка?
Вообще, нет.


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: Авварон от Сентябрь 21, 2011, 13:08
я правильно понял, вы хотите чтобы у сущности вью поведение на ретурн зависило от редактировани/нередактирование.
значит поведение ретурн должно быть реализовано во вью. наследование и переопределение keypress(event).
далее вы хотите чтобы в приложении был экшн который бы открывал файл выделенный во вью.
значит слот экшна должен открывать файл(вью->currentIndex()).
Кроме того я услышал, что у вас есть экшны и в меню. Это некорректно, экшн такая сущность которая должна пристуствовать в одном экземпляре.

Так делать некорректно.
Код:
    QModelIndexList indexes = d->selectedIndexes();
    if (indexes.count() != 1) {
//        emit error();
    } else {
        d->currentView->edit(indexes.first());

Надо так:
Код:
        d->currentView->edit(d->currentView->currentIndex());
Да, я тоже склоняюсь к переопределению ретурна во вью.

Экшны могут быть в 1м экземпляре, если вы пишите приложение со статической иерархией виджетов, к-ая заранее известна. тога можно коннектить экшны к слотам в мейнвиндоу и спускаться по иерархии вниз, дергая методы. В моем случае неизвестно, что за виджет будет в табе, поэтому приходится использовать другой способ, с дублированием экшнов. Можно конечно перестраивать меню каждый раз когда перелючаем фокус, но это медленнее будет.
За currentIndex() спаибо, попробую, не знал про такой метод.


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: asvil от Сентябрь 21, 2011, 17:09
Именно для того чтобы экшну было пофиг на то какие виджеты в табе, придумали в ооп интерфейсы, а кутешники еще и придумали/на самом деле позаимствовали, динамический вызов методов.
В слоте экшна вы можете проверить, имеются ли у виджета под фокусом методы openFile, editFile, removeFile etc, и сделать им focusWidget()->metaObject()->invokeMethod(focusWidget, "openFile");
И теперь в filemanagerview создать слот с именем openFile, в котором реализовать данную логику.
У данного подхода есть минус, он использует widget с фокусом. Фокус вещь ненадежная, поэтому вместо фокуса можно просто перебирать детей текущей вкладки.
Кстати я при переключении фокуса меню не перестраивал, а просто дисейблил экшены.


Название: Re: Пересечение эдит тригеров с экшном
Отправлено: Авварон от Сентябрь 22, 2011, 09:29
90% экшнов должны работать вне зависимости от фокуса. При этом при смене контекста - списка активных виджетов, помимо того, что нужно будет задисейблить все экшны, нажо будет еще чекнуть/анчекнуть чекабл экшны, в зависимости от нового списка виджетов (пример - в1 одной табе показан тулбар, в другой - нет). Сделать это можно только руками и это означает на каждый чих искать в хэше "свой" виджет и переключать экшны в зависимости от его стейта.