2011-12-22 3 views
5

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

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

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

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

Update: Вот что я пытался не повезло:

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.

ответ

0

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

The shortcut is set in QMdiSubWindowPrivate::createSystemMenu() during the construction of a QMdiSubWindow, I doubt that you can remove it without having to patch Qt libs.

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

0

Подкласс QMdiArea и reimplement 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; 
} 
+0

поэтому не существует никакого способа отключить ярлык, который QMdiArea создан?В основном это означает, что если я хочу использовать короткий ключ, я должен использовать соединения между сигналами/слотами между ними? – Serodis

+0

Кроме того, если это абсолютно единственный способ, есть ли какой-либо вред, если вы оставите двусмысленный ярлык? IE: Установка ярлыка в меню виджетов? Я действительно не хочу жертвовать ярлыком «Ctrl + W» в панели меню, так как это лучший способ сказать пользователю функцию ярлыков. – Serodis

+0

Чтобы изменить поведение QMdiArea по умолчанию в отношении конкретного ключевого события, необходимо подклассифицировать его и повторно реализовать 'keyPressEvent()'. Другой способ - использовать фильтры событий. – Arlen

2

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

QMdiSubWindow *subWindow2 = mdiArea.addSubWindow(internalWidget2, 
               Qt::Widget | Qt::CustomizeWindowHint | 
               Qt::WindowMinMaxButtonsHint); 
0

Мне удалось обойти это, установив контекст контекста для моего действия. Установив его на 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

Вы можете отключить этот ярлык, как это:

for(QAction *action : subWindow->systemMenu()->actions()) { 
    if(action->shortcut() == QKeySequence(QKeySequence::Close)) { 
     action->setShortcut(QKeySequence()); 
     break; 
    } 
}