Qt - Удалить ярлык - Неоднозначная перегрузка ярлыка - PullRequest
5 голосов
/ 22 декабря 2011

Посторонняя информация: Я пытаюсь создать приложение, используя Qt. Это приложение имеет QMdiArea и дочернее окно. Мое дочернее окно будет иметь меню, которое может быть интегрировано в QMdiArea или выделено и привязано к самому ребенку. Хотя это немного больше деталей, чем нужно ...

проблема: Я бы хотел, чтобы у моего дочернего виджета было меню с ярлыком "CTRL + W". Но поскольку я использую QMdiArea, ярлык уже используется, вызывая:

QAction :: eventFilter: Неоднозначная перегрузка ярлыка: Ctrl + W

Как мне избавиться от этого ярлыка и использовать его в своем дочернем виджете?

Обновление: Вот что я попробовал без удачи:

class MDI : public QMdiArea
{
    Q_OBJECT
    private:
    bool event(QEvent *tEvent)
    {
        if (tEvent->type() == QEvent::KeyPress)
        {
            QKeyEvent* ke = static_cast<QKeyEvent*>(tEvent);
            if (ke->key()== Qt::Key_W && ke->modifiers() & Qt::ControlModifier)
            emit KeyCW();
            return true;
        }
        return QMdiArea::event(tEvent);
    }
public:
signals:
    void KeyCW();
};

Это работает, если я делаю что-то столь же простое, как изменение Qt::Key_W на Qt::Key_L.. Получается комбинация клавиш и генерируется событие. С W этого просто не бывает. Я также попытался переместить event в QMainWindow, а также EventFilter в подокне в QMdiArea. Кажется, что это немного слишком сложно сделать так просто, как удалить обработчики ключей по умолчанию из QMdiArea.

Ответы [ 5 ]

2 голосов
/ 20 июля 2017

Вы можете отключить этот ярлык следующим образом:

for( QAction *action : subWindow->systemMenu()->actions() ) {
    if( action->shortcut() == QKeySequence( QKeySequence::Close ) ) {
        action->setShortcut( QKeySequence() );
        break;
    }
}
2 голосов
/ 14 февраля 2012

Вы можете полностью избавиться от предопределенного действия закрытия QMdiSubWindow, используя Qt::CustomizeWindowHint в качестве дополнительного флага при добавлении подокна.

QMdiSubWindow *subWindow2 = mdiArea.addSubWindow(internalWidget2, 
                                                 Qt::Widget | Qt::CustomizeWindowHint | 
                                                 Qt::WindowMinMaxButtonsHint);
0 голосов
/ 28 марта 2012

Мне удалось обойти это, установив контекст ярлыка для моего близкого действия.Установив значение Qt::WidgetShortcut, я больше не получаю неоднозначную перегрузку ярлыка.Вот как я сейчас настраиваю свое близкое действие:

  closeAction = new QAction(tr("&Close"), this);
  closeAction->setShortcut(Qt::CTRL|Qt::Key_W);
  closeAction->setShortcutContext(Qt::WidgetShortcut);
  connect(closeAction, SIGNAL(triggered()), mdiArea, SLOT(closeActiveSubWindow()));
0 голосов
/ 24 декабря 2011

Из того, что я могу сказать, то, что я ищу, невозможно без написания моей собственной MDIArea.

Ярлык устанавливается в QMdiSubWindowPrivate :: createSystemMenu () во время построенияQMdiSubWindow, я сомневаюсь, что вы можете удалить его без необходимости исправления библиотек Qt.

Надеюсь, в какой-то момент кто-то опровергнет это или QT внесет изменения.Между тем, похоже, что нам всем нужно держаться подальше от этих предварительно назначенных ярлыков.

0 голосов
/ 22 декабря 2011

Подкласс QMdiArea и переопределение keyPressEvent(). Это должно сработать.

  void keyPressEvent(QKeyEvent* event){

    if(event->key() == Qt::Key_W and event->modifiers() & Qt::ControlModifier){
      // handle it
    }else{
      return QMdiArea::keyPressEvent(event);
    }
  }

Вы также можете использовать фильтры событий. Мне не хватает вашей иерархии классов, но я надеюсь, что вы поняли идею.

bool CustomMdiArea::eventFilter(QObject *object, QEvent *event){
     if(object == yourChildWindow && event->type() == QEvent::KeyPress) {
         QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
         if(keyEvent->key() == Qt::Key_W and keyEvent->modifiers() & Qt::ControlModifier) {
             //handle it
             return true;
         }else{
             return false;
         }
     }
     return false;
 }
...