2010-01-12 1 views
7

Saluti,Come implementare il menu "Modifica" con "Annulla", "Taglia", "Incolla" e "Copia"?

per una delle mie applicazioni Sto tentando di implementare un menu "Modifica". Questo menu di solito ha la norma-voci Undo, Cut, Copia e Incolla.

Questo menu non è lì per impostazione predefinita, e gli utenti sembrano aspettarsi che soprattutto su Mac OS X.

Esiste un modo più semplice di un dell'applicazione del presente, senza farlo in ogni widget di manualmente? Poiché la maggior parte dei widget ha il meccanismo di copia/incolla/annulla già implementato tramite scorciatoie, vorrei fornire alcune semplici azioni di menu che li chiamano.

Le azioni devono chiamare prima qualsiasi oggetto abbia il focus, quindi devono passare gli eventi in alto alla catena di oggetti, immagino.

sto usando Qt 4.6 su Windows, Linux e Mac OS X.

Grazie!

risposta

6

È abbastanza facile ottenere la metà delle funzionalità necessarie. Basta creare il menu Modifica, insieme alle necessarie QActions (copia/incolla/annulla/ecc.) Nella classe della finestra principale e collegarle agli slot. Negli slot, emula il tasto corretto per premere e rilasciare gli eventi (ad esempio Ctrl + C per Copia) e inviarli al widget attualmente attivo. Nel codice, qualcosa del genere:

MainWindow::MainWindow(...) 
{ 
    ... 
    connect(actionCopy, SIGNAL(triggered()), SLOT(copy())); 
    ... 
} 
... 
void MainWindow::copy() 
{ 
    QWidget* focused = QApplication::focusWidget(); 
    if(focused != 0) 
    { 
     QApplication::postEvent(focused, 
           new QKeyEvent(QEvent::KeyPress, 
               Qt::Key_C, 
               Qt::ControlModifier)); 
     QApplication::postEvent(focused, 
           new QKeyEvent(QEvent::KeyRelease, 
               Qt::Key_C, 
               Qt::ControlModifier)); 
} 

Naturalmente, questo è piuttosto un hack. È necessario modificare il codice per ciascuna piattaforma di destinazione, modificando le scorciatoie da tastiera con quelle corrette, e potrebbe accadere che un widget che riceve lo stato attivo inaspettato con Ctrl + C. Il peggior aspetto negativo di questo metodo, a mio avviso, è che non è possibile controllare correttamente lo stato abilitato delle voci del menu Modifica. Non è possibile interrogare da un widget generico se un'operazione di copia o incolla sarebbe possibile o meno.

Non riesco a trovare una soluzione reale a questo problema - e sarei sorpreso di scoprire che ne esiste uno - poiché la funzionalità di copia/incolla è generalmente nascosta all'interno del codice della classe e non viene esposta attraverso alcun set standard di segnali/slot. Dopo gli esperimenti di stasera con la funzionalità, ho deciso di dimenticarmi di avere un menu Modifica dalla mia applicazione e mi aspetto che gli utenti conoscano le scorciatoie da tastiera o che utilizzino i menu sensibili al contesto.

+1

Notizie terribili. Grazie comunque – aehlke

0

La mia impressione è che il menu Modifica si applica al widget del documento centrale, non a molti di quelli piccoli. Non ho provato, ma se hai un modulo con QLineEdits, il menu Modifica (nella barra dei menu) si applica davvero a quel widget. Non è semplice aprire il menu contestuale o premere le scorciatoie per accedere a queste opzioni ...

+2

Ciò potrebbe essere vero per Windows/Linux come gestori di finestre. Su OS X, tuttavia, nella parte superiore dello schermo è presente una barra dei menu a livello di applicazione, non nella parte superiore di ogni finestra. E gli utenti Mac si aspettano che l'azione del menu selezionata abbia un effetto sulla finestra più in alto e sul widget attualmente attivo. (Selezionando Incolla si incollerebbe tutto ciò che è presente negli Appunti in QLineEdit che ha attualmente lo stato attivo, ecc.) – BastiBen

0

La soluzione dell'utente285740 non mi è stata di aiuto, dal momento che utilizzo un controllo del browser nella mia app (CEF o WebKit, non importa).

Perché? Per i browser, focusWidget() sembra essere sempre NULL, poiché gli elementi <input> non sono widget. Ho provato postEvent() ad altri widget - non ha funzionato. L'aggiunta di voci di menu con QAction::TextHeuristicRole + sequenze standard come QKeySequence::Copy non ha eseguito il lavoro (potevo collegarle solo ai miei slot, non agli slot standard). L'esempio di Cefclient carica un file xib, ma non è un'opzione per me, dal momento che Qt crea tutto da zero.

Alla fine, ho trovato la soluzione! Crea gli stessi elementi del menu dal codice ObjectiveC++. Si comportano come quelli creati tramite QMenuBar, ma possono essere collegati a dei veri e propri azioni automatiche come @selector(copy:)

È possibile trovare un esempio qui (!): nsMenuUtilsX::GetStandardEditMenuItem(), basta farlo dal codice objC++.

Tuttavia, questo codice non funziona se lo si esegue prima dello QApplication::exec(). Quindi "riscrive" il menu principale a livello di programmazione ... Come risolvere il problema? Bene, forse aggiungerò qualche trucco come un QTimer. Non lo fa se non si tenta di aggiungere altri oggetti tramite QMenuBar. È a posto adesso! Menu indipendente da Qt.