#include "QtApp.h" int main ( int argc, char** argv) { QtApp app ( argc, argv ); app.setFirstWindow(); return app.exec(); }
Your custom code, say to generate the DataSource data should be inserted before the call to app.exec()
as that function starts the Qt event loop and doesn't return until the application is terminated.
If you already have a Qt application, then you can add the HippoDraw CanvasWindow and Inspector to your application by adding code to your main with something like the implementation of QtApp::setFirstWindow does. The result might look like this ...
#include "qt/CanvasWindow.h" #include "qapplication.h" int main ( int argc, char** argv) { MyApp app ( argc, argv ); CanvasWindow * window = new CanvasWindow (); window->show(); return app.exec(); }
One doesn't need to create the CanvasWindow before starting the Qt event loop. It can be created at any time.
First the QApplication object is created and the NTupleController is used to create an NTuple by reading a file as shown here.
int main ( int argc, char **argv ) { QApplication app ( argc, argv ); const string filename ( "../../../hippodraw/examples/aptuple.tnt" ); NTupleController * nt_controller = NTupleController::instance (); NTuple * nt = nt_controller->createNTuple ( filename );
In a custom application, you will probably have other ways of creating the NTuple. If you want the NTuple visible to the Inspector, then you must register it with the NTupleController like this ...
NTuple * nt = // create your NTuple somehow NTupleController * nt_controller = NTupleController::instance (); nt_controller->registerNTuple ( nt );
Next a display is created bound to the NTuple and one of its columns.
const string histo ( "Histogram" ); vector < string > bindings; bindings.push_back ( "Cost" ); DisplayController * dc_controller = DisplayController::instance (); PlotterBase * plotter = dc_controller->createDisplay ( histo, *nt, bindings );
Note that DisplayController creates the appropriate class derived from PlotterBase for the kind of display you requested.
Plotter objects are used both for canvas items and widgets. In this case, a QtViewWidget is created and the plotter is attached to it.
QtViewWidget * view = new QtViewWidget ( ); view->setPlotter ( plotter );
Finally, the view it set into the Qt main window, resized, captioned, and the event loop started.
view->resize ( 200, 200 ); app.setMainWidget( view ); view->setCaption ( "Qt HippoDraw - View widget" ); view->show(); int result = a.exec();
Note that the above code used methods that QtViewWidget inherits from Qt's QWidget class.
Don't forget to clean up when you are done.
delete view; delete nt; return result; }
The resulting application window looks like this ...
QtViewWidget set as application's main window.
The complete code is shown below ...
00001 00007 #include "qt/QtViewWidget.h" 00008 00009 #include "controllers/DisplayController.h" 00010 #include "datasrcs/NTupleController.h" 00011 #include "datasrcs/NTuple.h" 00012 #include "plotters/PlotterBase.h" 00013 00014 #include <qapplication.h> 00015 00016 #include <string> 00017 #include <vector> 00018 00019 using std::string; 00020 using std::vector; 00021 00022 00029 int main ( int argc, char **argv ) 00030 { 00031 QApplication a( argc, argv ); 00032 00033 const string filename ( "../../../hippodraw/examples/aptuple.tnt" ); 00034 NTupleController * nt_controller = NTupleController::instance (); 00035 DataSource * nt 00036 = nt_controller->createNTuple ( filename ); 00037 00038 const string histo ( "Histogram" ); 00039 vector < string > bindings; 00040 bindings.push_back ( "Cost" ); 00041 00042 DisplayController * dc_controller = DisplayController::instance (); 00043 PlotterBase * plotter 00044 = dc_controller->createDisplay ( histo, *nt, bindings ); 00045 00046 QtViewWidget * view = new QtViewWidget ( ); 00047 view->setPlotter ( plotter ); 00048 00049 view->resize ( 200, 200 ); 00050 a.setMainWidget( view ); 00051 view->setCaption ( "Qt HippoDraw - View widget" ); 00052 view->show(); 00053 00054 int result = a.exec(); 00055 00056 delete view; 00057 delete nt; 00058 00059 return result; 00060 }
#include <qapplication.h> #include "QtViewWidgetWindow.h" int main( int argc, char ** argv ) { QApplication app ( argc, argv ); QtViewWidgetWindow w; w.show(); app.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) ); return app.exec(); }
In this example, the class QtViewWidgetWindow was built with Qt Designer. It was created by asking for a new main window. QtViewWidget was inserted in Qt Designer as a custom widget. The results look like this ...
QtViewWidget as custom widget
In this example, the fileOpen() slot as implemented like the implementation in the Custom application with canvas example. But in addition, the implementation creates an Inspector and signals it to update itself with the created plotter. The code look like this ...
m_inspector = new Inspector (); m_inspector->show(); QCustomEvent * event = new QCustomEvent ( QEvent::User, plotter ); QApplication::postEvent ( m_inspector, event );
One might have expected a direct call to Inspector::update following the Observer pattern instead of this implementation. However, it was found that under the Windows operating system, such a direct call caused problems with the OS's threading model. So the QCustomEvent is used to avoid the problem.
Some part of the application may cause a change to the plotter. When that happens, one needs to update the Inspector. Following the Observer pattern, when something in the plotter changes, it sends an update message to its observer which is the QtViewWidget. It in turn, needs to send a message to its parent which is the QtViewWidgetWindow object. It uses a QCustomEvent to do this, so the implementation of the QtViewWidgetWindow must implement it something like this ...
void QtViewWidgetWindow::customEvent ( QCustomEvent * event ) { void * data = event->data(); QCustomEvent * e = new QCustomEvent ( QEvent::User, data ); QApplication::postEvent ( m_inspector, e ); }
After opening the file, the window looks like this ...
QtViewWidgetWindow after opening file
The complete source code is show below ...
00001 /* -*- mode: c++ -*- */ 00002 /**************************************************************************** 00003 ** ui.h extension file, included from the uic-generated form implementation. 00004 ** 00005 ** If you wish to add, delete or rename functions or slots use 00006 ** Qt Designer which will update this file, preserving your code. Create an 00007 ** init() function in place of a constructor, and a destroy() function in 00008 ** place of a destructor. 00009 *****************************************************************************/ 00010 00011 using std::string; 00012 using std::vector; 00013 00016 void QtViewWidgetWindow::init() 00017 { 00018 00019 } 00020 00021 void QtViewWidgetWindow::fileOpen() 00022 { 00023 QString file_name 00024 = QFileDialog::getOpenFileName ( QString::null, // starting directory 00025 "ntuple (*.*)", // filter 00026 this, // parent 00027 "open ntuple file", // internal name 00028 "Open ntuple" ); // actual window caption 00029 if ( file_name.isEmpty () ) return; 00030 00031 #if QT_VERSION < 0x030100 // 3.1.0 00032 const string filename ( file_name ); 00033 #else 00034 const string filename( file_name.latin1() ); 00035 #endif 00036 NTupleController * nt_controller = NTupleController::instance (); 00037 DataSource * nt 00038 = nt_controller->createNTuple ( filename ); 00039 00040 const string histo ( "Histogram" ); 00041 vector < string > bindings; 00042 bindings.push_back ( "Cost" ); 00043 00044 DisplayController * dc_controller = DisplayController::instance (); 00045 PlotterBase * plotter 00046 = dc_controller->createDisplay ( histo, *nt, bindings ); 00047 00048 m_view->setPlotter ( plotter ); 00049 00050 m_inspector = new Inspector (); 00051 m_view -> setInspector ( m_inspector ); 00052 00053 m_inspector->show(); 00054 m_view->update ( plotter ); 00055 PlotterEvent * event = new PlotterEvent ( plotter ); 00056 QApplication::postEvent ( m_inspector, event ); 00057 } 00058 00059 void QtViewWidgetWindow::filePrint() 00060 { 00061 00062 } 00063 00064 void QtViewWidgetWindow::fileExit() 00065 { 00066 qApp->quit(); 00067 } 00068 00069 void QtViewWidgetWindow::helpAbout() 00070 { 00071 00072 }