Pues mira, yo te propongo una solución algo diferente.
Pasos a seguir:
1. Crea una función miembro en la ventana principal tal que:
Código C++:
Ver originalclass MainWindow : public QMainWindow
{
private:
template< typename Class >
QDialog* NewWindow( )
{
return new Class( this );
}
};
Este template nos va a permitir crear cualquier ventana que herede de QDialog. Ahora veremos cómo usarla.
2. Creamos un mapa que nos permita asociar los QAction. En este caso, cada QAction irá asociado a la llamada correcta a la función que hemos creado en el paso anterior. Esto lo conseguimos así:
Código C++:
Ver original#include <functional>
#include <map>
class MainWindow
{
private:
std::map< QAction*, std::function< QDialog*( MainWindow* ) > > _newWindows;
};
Usamos std::function por legibilidad más que nada. El mapa anterior tiene como clave un QAction. El segundo parámetro es un puntero a una función miembro de MainWindow, con el siguiente prototipo: "QDialog* MainWindow::X( )".
3. Rellenamos el mapa. Esto lo suyo sería hacerlo en una función que se llame desde el constructor, para mantener la limpieza del código:
Código C++:
Ver originalQAction* newAction = new QAction( "Test", this );
connect( newAction, SIGNAL( triggered( ) ), this, SLOT( MenuTriggered( ) ) );
QMenu* menu = menuBar( )->addMenu( "File" );
menu->addAction( newAction );
_newWindows[ newAction ] = &MainWindow::NewWindow< TestDialog >;
En el ejemplo estamos creando primero el QAction, por defecto, todos los QAction llamarán al slot MenuTriggered( ), ahí es donde terminaremos de obrar la magia. A continuación añadimos el QAction al menu. Finalmente añadimos una entrada en el mapa creado anteriormente. En este caso "TestDialog" es el nombre de un diálogo que he creado para la ocasión. Lo que estamos haciendo en esta última línea es devolver el puntero a una versión especializada de "NewWindow" que nos devolverá un objeto de tipo "TestDialog".
4. Para terminar, el código del slot. Este código después se puede ampliar para hacer comprobaciones o para añadir otro tipo de opciones:
Código C++:
Ver originalvoid MainWindow::MenuTriggered( )
{
auto it = _newWindows.find( dynamic_cast< QAction* >( sender( ) ) );
if( it != _newWindows.end( ) )
{
QDialog* dlg = it->second( this );
dlg->exec( );
}
}
La función "sender" está presente en todos los QObject y almacena el objeto que ha generado la última señal... en nuestro caso el objeto en cuestión será el QAction sobre el que hayamos clickado. Una vez tenemos el objeto en cuestión, buscamos en el mapa para conocer cual es la función a la que debemos llamar... la llamamos y lanzamos la ventana que corresponda. Magia!!! jejejeje
Espero que te sirva esta solución.
Un saludo