2010-01-12 20 views
7

Saludos,¿Cómo implementar el menú "Editar" con "Deshacer", "Cortar", "Pegar" y "Copiar"?

para una de mis aplicaciones Estoy tratando de implementar un menú "Editar". Este menú tiene generalmente la norma-entradas Deshacer, Cortar , Copiar y Pegar .

Este menú no está allí por defecto, y los usuarios parecen esperar que sea especialmente en Mac OS X.

¿Hay una manera más fácil de implementar un presente, sin hacerlo en todos los widget de forma manual? Como la mayoría de los widgets tienen el mecanismo de copiar/pegar/deshacer que ya se implementó a través de accesos directos, me gustaría ofrecer algunas simples acciones de menú que también los llamen.

Las acciones deberían llamar primero a cualquier widget que tenga el foco, entonces deberían pasar los eventos hacia arriba de la cadena de objetos, supongo.

estoy usando Qt 4.6 en Windows, Linux y Mac OS X.

Gracias!

Respuesta

6

Es bastante fácil lograr la mitad de la funcionalidad necesaria. Simplemente cree el menú Editar, junto con las QActions necesarias (copiar/pegar/deshacer, etc.) en su clase de ventana principal y conéctelas a las ranuras. En las ranuras, emule la pulsación correcta de la tecla y suelte los eventos (por ejemplo, Ctrl + C para Copiar) y envíelos al widget actualmente enfocado. En el código, algo como esto:

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)); 
} 

Por supuesto, esto es todo un truco. Necesita modificar el código para cada plataforma de destino, cambiando los atajos de teclado a los correctos, y podría suceder que un widget que recibe el foco haga algo silencioso inesperado con Ctrl + C. La peor desventaja de este método, en mi opinión, es que no se puede controlar correctamente el estado habilitado de los elementos del menú Editar. No es posible consultar desde un widget genérico si una operación de copiar o pegar sería posible o no.

No puedo encontrar una solución real a este problema, y ​​me sorprendería saber que existe, ya que la funcionalidad de copiar/pegar generalmente está oculta dentro del código de clase y no está expuesta a ningún conjunto estándar de señales/máquinas tragamonedas. Después de los experimentos de esta noche con la funcionalidad, he decidido olvidarme de tener un menú Editar de mi aplicación y esperar que los usuarios conozcan los atajos de teclado, o usar los menús contextuales.

+1

Noticias terribles. Gracias aunque – aehlke

0

Mi impresión es que el menú Editar se aplica al widget del documento central, no a muchos pequeños. No he probado, pero si tiene un formulario con QLineEdits, ¿el menú Editar (en la barra de menú) realmente se aplica a ese widget. ¿No es sencillo abrir el menú contextual o presionar los atajos para acceder a estas opciones ...

+2

Eso podría ser cierto para Windows/Linux como los administradores de ventanas. En OS X, sin embargo, tiene una barra de menú de toda la aplicación en la parte superior de la pantalla, no en la parte superior de cada ventana. Y los usuarios de Mac esperan que la acción de menú seleccionada tenga un efecto en la ventana superior y en el widget que actualmente tiene el foco. (Seleccionar pegar pegaría todo lo que está en el portapapeles en el QLineEdit que actualmente tiene el foco, etc.) – BastiBen

0

La solución de user285740 no me ayudó, ya que estoy usando un control de navegador en mi aplicación (CEF o WebKit, no importa).

¿Por qué? Para navegadores, focusWidget() siempre parece ser NULL, ya que los elementos <input> no son widgets. Intenté postEvent() con otros widgets, pero no funcionó. Agregar elementos de menú con QAction::TextHeuristicRole + secuencias estándar como QKeySequence::Copy tampoco hizo el trabajo (podría conectarlos solo a mis ranuras, no a las ranuras estándar). La muestra de Cefclient carga un archivo xib, pero no es una opción para mí, ya que Qt crea todo desde cero.

¡Finalmente, encontré la solución! Cree los mismos elementos de menú del código de ObjectiveC++. Actúan como los creados a través de QMenuBar, pero pueden estar conectados a algunas acciones automáticas reales como @selector(copy:)

puede encontrar un ejemplo aquí (!): nsMenuUtilsX::GetStandardEditMenuItem(), acaba de hacer que a partir de su código ObjC++.

Pero este código no funciona si lo ejecuta antes de QApplication::exec(). Qt luego "reescribe" el menú principal mediante programación ... ¿Cómo solucionar eso? Bueno, tal vez agregue algunos hack como un QTimer. No hace eso si no intenta agregar otros artículos a través de QMenuBar. ¡Ahora está bien! Qt-menú independiente.

Cuestiones relacionadas