Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |
This is a complete example program with a main window, menus and toolbars. The main widget is a TQCanvas, and this example demonstrates basic canvas usage.
Project file:
TEMPLATE = app CONFIG += warn_on REQUIRES = full-config HEADERS += element.h \ canvastext.h \ canvasview.h \ chartform.h \ optionsform.h \ setdataform.h SOURCES += element.cpp \ canvasview.cpp \ chartform.cpp \ chartform_canvas.cpp \ chartform_files.cpp \ optionsform.cpp \ setdataform.cpp \ main.cpp
Header files:
#ifndef ELEMENT_H #define ELEMENT_H #include <ntqcolor.h> #include <ntqnamespace.h> #include <ntqstring.h> #include <tqvaluevector.h> class Element; typedef TQValueVector<Element> ElementVector; /* Elements are valid if they have a value which is > EPSILON. */ const double EPSILON = 0.0000001; // Must be > INVALID. class Element { public: enum { INVALID = -1 }; enum { NO_PROPORTION = -1 }; enum { MAX_PROPOINTS = 3 }; // One proportional point per chart type Element( double value = INVALID, TQColor valueColor = TQt::gray, int valuePattern = TQt::SolidPattern, const TQString& label = TQString::null, TQColor labelColor = TQt::black ) { init( value, valueColor, valuePattern, label, labelColor ); for ( int i = 0; i < MAX_PROPOINTS * 2; ++i ) m_propoints[i] = NO_PROPORTION; } ~Element() {} bool isValid() const { return m_value > EPSILON; } double value() const { return m_value; } TQColor valueColor() const { return m_valueColor; } int valuePattern() const { return m_valuePattern; } TQString label() const { return m_label; } TQColor labelColor() const { return m_labelColor; } double proX( int index ) const; double proY( int index ) const; void set( double value = INVALID, TQColor valueColor = TQt::gray, int valuePattern = TQt::SolidPattern, const TQString& label = TQString::null, TQColor labelColor = TQt::black ) { init( value, valueColor, valuePattern, label, labelColor ); } void setValue( double value ) { m_value = value; } void setValueColor( TQColor valueColor ) { m_valueColor = valueColor; } void setValuePattern( int valuePattern ); void setLabel( const TQString& label ) { m_label = label; } void setLabelColor( TQColor labelColor ) { m_labelColor = labelColor; } void setProX( int index, double value ); void setProY( int index, double value ); #ifdef TQ_FULL_TEMPLATE_INSTANTIATION // xlC 3.x workaround TQ_DUMMY_COMPARISON_OPERATOR(Element) bool operator!=( const Element& e) const { return ( !(e == *this) ); } #endif private: void init( double value, TQColor valueColor, int valuePattern, const TQString& label, TQColor labelColor ); double m_value; TQColor m_valueColor; int m_valuePattern; TQString m_label; TQColor m_labelColor; double m_propoints[2 * MAX_PROPOINTS]; }; TQTextStream &operator<<( TQTextStream&, const Element& ); TQTextStream &operator>>( TQTextStream&, Element& ); #endif
#ifndef CHARTFORM_H #define CHARTFORM_H #include "element.h" #include <ntqmainwindow.h> #include <ntqstringlist.h> class CanvasView; class TQAction; class TQCanvas; class TQFont; class TQPrinter; class TQString; class ChartForm: public TQMainWindow { TQ_OBJECT public: enum { MAX_ELEMENTS = 100 }; enum { MAX_RECENTFILES = 9 }; // Must not exceed 9 enum ChartType { PIE, VERTICAL_BAR, HORIZONTAL_BAR }; enum AddValuesType { NO, YES, AS_PERCENTAGE }; ChartForm( const TQString& filename ); ~ChartForm(); int chartType() { return m_chartType; } void setChanged( bool changed = TRUE ) { m_changed = changed; } void drawElements(); TQPopupMenu *optionsMenu; // Why public? See canvasview.cpp protected: virtual void closeEvent( TQCloseEvent * ); private slots: void fileNew(); void fileOpen(); void fileOpenRecent( int index ); void fileSave(); void fileSaveAs(); void fileSaveAsPixmap(); void filePrint(); void fileQuit(); void optionsSetData(); void updateChartType( TQAction *action ); void optionsSetFont(); void optionsSetOptions(); void helpHelp(); void helpAbout(); void helpAboutTQt(); void saveOptions(); private: void init(); void load( const TQString& filename ); bool okToClear(); void drawPieChart( const double scales[], double total, int count ); void drawVerticalBarChart( const double scales[], double total, int count ); void drawHorizontalBarChart( const double scales[], double total, int count ); TQString valueLabel( const TQString& label, double value, double total ); void updateRecentFiles( const TQString& filename ); void updateRecentFilesMenu(); void setChartType( ChartType chartType ); TQPopupMenu *fileMenu; TQAction *optionsPieChartAction; TQAction *optionsHorizontalBarChartAction; TQAction *optionsVerticalBarChartAction; TQString m_filename; TQStringList m_recentFiles; TQCanvas *m_canvas; CanvasView *m_canvasView; bool m_changed; ElementVector m_elements; TQPrinter *m_printer; ChartType m_chartType; AddValuesType m_addValues; int m_decimalPlaces; TQFont m_font; }; #endif
Implementation:
#include "canvasview.h" #include "chartform.h" #include "optionsform.h" #include "setdataform.h" #include <ntqaction.h> #include <ntqapplication.h> #include <ntqcombobox.h> #include <ntqfile.h> #include <ntqfiledialog.h> #include <ntqfont.h> #include <ntqfontdialog.h> #include <ntqmenubar.h> #include <ntqmessagebox.h> #include <ntqpixmap.h> #include <ntqpopupmenu.h> #include <ntqprinter.h> #include <ntqradiobutton.h> #include <ntqsettings.h> #include <ntqspinbox.h> #include <ntqstatusbar.h> #include <ntqtoolbar.h> #include <ntqtoolbutton.h> #include "images/file_new.xpm" #include "images/file_open.xpm" #include "images/file_save.xpm" #include "images/file_print.xpm" #include "images/options_setdata.xpm" #include "images/options_setfont.xpm" #include "images/options_setoptions.xpm" #include "images/options_horizontalbarchart.xpm" #include "images/options_piechart.xpm" #include "images/options_verticalbarchart.xpm" const TQString WINDOWS_REGISTRY = "/Trolltech/TQtExamples"; const TQString APP_KEY = "/Chart/"; ChartForm::ChartForm( const TQString& filename ) : TQMainWindow( 0, 0, WDestructiveClose ) { setIcon( TQPixmap( options_piechart ) ); TQAction *fileNewAction; TQAction *fileOpenAction; TQAction *fileSaveAction; TQAction *fileSaveAsAction; TQAction *fileSaveAsPixmapAction; TQAction *filePrintAction; TQAction *fileQuitAction; TQAction *optionsSetDataAction; TQAction *optionsSetFontAction; TQAction *optionsSetOptionsAction; fileNewAction = new TQAction( "New Chart", TQPixmap( file_new ), "&New", CTRL+Key_N, this, "new" ); connect( fileNewAction, TQ_SIGNAL( activated() ), this, TQ_SLOT( fileNew() ) ); fileOpenAction = new TQAction( "Open Chart", TQPixmap( file_open ), "&Open...", CTRL+Key_O, this, "open" ); connect( fileOpenAction, TQ_SIGNAL( activated() ), this, TQ_SLOT( fileOpen() ) ); fileSaveAction = new TQAction( "Save Chart", TQPixmap( file_save ), "&Save", CTRL+Key_S, this, "save" ); connect( fileSaveAction, TQ_SIGNAL( activated() ), this, TQ_SLOT( fileSave() ) ); fileSaveAsAction = new TQAction( "Save Chart As", TQPixmap( file_save ), "Save &As...", 0, this, "save as" ); connect( fileSaveAsAction, TQ_SIGNAL( activated() ), this, TQ_SLOT( fileSaveAs() ) ); fileSaveAsPixmapAction = new TQAction( "Save Chart As Bitmap", TQPixmap( file_save ), "Save As &Bitmap...", CTRL+Key_B, this, "save as bitmap" ); connect( fileSaveAsPixmapAction, TQ_SIGNAL( activated() ), this, TQ_SLOT( fileSaveAsPixmap() ) ); filePrintAction = new TQAction( "Print Chart", TQPixmap( file_print ), "&Print Chart...", CTRL+Key_P, this, "print chart" ); connect( filePrintAction, TQ_SIGNAL( activated() ), this, TQ_SLOT( filePrint() ) ); optionsSetDataAction = new TQAction( "Set Data", TQPixmap( options_setdata ), "Set &Data...", CTRL+Key_D, this, "set data" ); connect( optionsSetDataAction, TQ_SIGNAL( activated() ), this, TQ_SLOT( optionsSetData() ) ); TQActionGroup *chartGroup = new TQActionGroup( this ); // Connected later chartGroup->setExclusive( TRUE ); optionsPieChartAction = new TQAction( "Pie Chart", TQPixmap( options_piechart ), "&Pie Chart", CTRL+Key_I, chartGroup, "pie chart" ); optionsPieChartAction->setToggleAction( TRUE ); optionsHorizontalBarChartAction = new TQAction( "Horizontal Bar Chart", TQPixmap( options_horizontalbarchart ), "&Horizontal Bar Chart", CTRL+Key_H, chartGroup, "horizontal bar chart" ); optionsHorizontalBarChartAction->setToggleAction( TRUE ); optionsVerticalBarChartAction = new TQAction( "Vertical Bar Chart", TQPixmap( options_verticalbarchart ), "&Vertical Bar Chart", CTRL+Key_V, chartGroup, "Vertical bar chart" ); optionsVerticalBarChartAction->setToggleAction( TRUE ); optionsSetFontAction = new TQAction( "Set Font", TQPixmap( options_setfont ), "Set &Font...", CTRL+Key_F, this, "set font" ); connect( optionsSetFontAction, TQ_SIGNAL( activated() ), this, TQ_SLOT( optionsSetFont() ) ); optionsSetOptionsAction = new TQAction( "Set Options", TQPixmap( options_setoptions ), "Set &Options...", 0, this, "set options" ); connect( optionsSetOptionsAction, TQ_SIGNAL( activated() ), this, TQ_SLOT( optionsSetOptions() ) ); fileQuitAction = new TQAction( "Quit", "&Quit", CTRL+Key_Q, this, "quit" ); connect( fileQuitAction, TQ_SIGNAL( activated() ), this, TQ_SLOT( fileQuit() ) ); TQToolBar* fileTools = new TQToolBar( this, "file operations" ); fileTools->setLabel( "File Operations" ); fileNewAction->addTo( fileTools ); fileOpenAction->addTo( fileTools ); fileSaveAction->addTo( fileTools ); fileTools->addSeparator(); filePrintAction->addTo( fileTools ); TQToolBar *optionsTools = new TQToolBar( this, "options operations" ); optionsTools->setLabel( "Options Operations" ); optionsSetDataAction->addTo( optionsTools ); optionsTools->addSeparator(); optionsPieChartAction->addTo( optionsTools ); optionsHorizontalBarChartAction->addTo( optionsTools ); optionsVerticalBarChartAction->addTo( optionsTools ); optionsTools->addSeparator(); optionsSetFontAction->addTo( optionsTools ); optionsTools->addSeparator(); optionsSetOptionsAction->addTo( optionsTools ); fileMenu = new TQPopupMenu( this ); menuBar()->insertItem( "&File", fileMenu ); fileNewAction->addTo( fileMenu ); fileOpenAction->addTo( fileMenu ); fileSaveAction->addTo( fileMenu ); fileSaveAsAction->addTo( fileMenu ); fileMenu->insertSeparator(); fileSaveAsPixmapAction->addTo( fileMenu ); fileMenu->insertSeparator(); filePrintAction->addTo( fileMenu ); fileMenu->insertSeparator(); fileQuitAction->addTo( fileMenu ); optionsMenu = new TQPopupMenu( this ); menuBar()->insertItem( "&Options", optionsMenu ); optionsSetDataAction->addTo( optionsMenu ); optionsMenu->insertSeparator(); optionsPieChartAction->addTo( optionsMenu ); optionsHorizontalBarChartAction->addTo( optionsMenu ); optionsVerticalBarChartAction->addTo( optionsMenu ); optionsMenu->insertSeparator(); optionsSetFontAction->addTo( optionsMenu ); optionsMenu->insertSeparator(); optionsSetOptionsAction->addTo( optionsMenu ); menuBar()->insertSeparator(); TQPopupMenu *helpMenu = new TQPopupMenu( this ); menuBar()->insertItem( "&Help", helpMenu ); helpMenu->insertItem( "&Help", this, TQ_SLOT(helpHelp()), Key_F1 ); helpMenu->insertItem( "&About", this, TQ_SLOT(helpAbout()) ); helpMenu->insertItem( "About &TQt", this, TQ_SLOT(helpAboutTQt()) ); m_printer = 0; m_elements.resize( MAX_ELEMENTS ); TQSettings settings; settings.insertSearchPath( TQSettings::Windows, WINDOWS_REGISTRY ); int windowWidth = settings.readNumEntry( APP_KEY + "WindowWidth", 460 ); int windowHeight = settings.readNumEntry( APP_KEY + "WindowHeight", 530 ); int windowX = settings.readNumEntry( APP_KEY + "WindowX", -1 ); int windowY = settings.readNumEntry( APP_KEY + "WindowY", -1 ); setChartType( ChartType( settings.readNumEntry( APP_KEY + "ChartType", int(PIE) ) ) ); m_addValues = AddValuesType( settings.readNumEntry( APP_KEY + "AddValues", int(NO) )); m_decimalPlaces = settings.readNumEntry( APP_KEY + "Decimals", 2 ); m_font = TQFont( "Helvetica", 18, TQFont::Bold ); m_font.fromString( settings.readEntry( APP_KEY + "Font", m_font.toString() ) ); for ( int i = 0; i < MAX_RECENTFILES; ++i ) { TQString filename = settings.readEntry( APP_KEY + "File" + TQString::number( i + 1 ) ); if ( !filename.isEmpty() ) m_recentFiles.push_back( filename ); } if ( m_recentFiles.count() ) updateRecentFilesMenu(); // Connect *after* we've set the chart type on so we don't call // drawElements() prematurely. connect( chartGroup, TQ_SIGNAL( selected(TQAction*) ), this, TQ_SLOT( updateChartType(TQAction*) ) ); resize( windowWidth, windowHeight ); if ( windowX != -1 || windowY != -1 ) move( windowX, windowY ); m_canvas = new TQCanvas( this ); m_canvas->resize( width(), height() ); m_canvasView = new CanvasView( m_canvas, &m_elements, this ); setCentralWidget( m_canvasView ); m_canvasView->show(); if ( !filename.isEmpty() ) load( filename ); else { init(); m_elements[0].set( 20, red, 14, "Red" ); m_elements[1].set( 70, cyan, 2, "Cyan", darkGreen ); m_elements[2].set( 35, blue, 11, "Blue" ); m_elements[3].set( 55, yellow, 1, "Yellow", darkBlue ); m_elements[4].set( 80, magenta, 1, "Magenta" ); drawElements(); } statusBar()->message( "Ready", 2000 ); } ChartForm::~ChartForm() { delete m_printer; } void ChartForm::init() { setCaption( "Chart" ); m_filename = TQString::null; m_changed = FALSE; m_elements[0] = Element( Element::INVALID, red ); m_elements[1] = Element( Element::INVALID, cyan ); m_elements[2] = Element( Element::INVALID, blue ); m_elements[3] = Element( Element::INVALID, yellow ); m_elements[4] = Element( Element::INVALID, green ); m_elements[5] = Element( Element::INVALID, magenta ); m_elements[6] = Element( Element::INVALID, darkYellow ); m_elements[7] = Element( Element::INVALID, darkRed ); m_elements[8] = Element( Element::INVALID, darkCyan ); m_elements[9] = Element( Element::INVALID, darkGreen ); m_elements[10] = Element( Element::INVALID, darkMagenta ); m_elements[11] = Element( Element::INVALID, darkBlue ); for ( int i = 12; i < MAX_ELEMENTS; ++i ) { double x = (double(i) / MAX_ELEMENTS) * 360; int y = (int(x * 256) % 105) + 151; int z = ((i * 17) % 105) + 151; m_elements[i] = Element( Element::INVALID, TQColor( int(x), y, z, TQColor::Hsv ) ); } } void ChartForm::closeEvent( TQCloseEvent * ) { fileQuit(); } void ChartForm::fileNew() { if ( okToClear() ) { init(); drawElements(); } } void ChartForm::fileOpen() { if ( !okToClear() ) return; TQString filename = TQFileDialog::getOpenFileName( TQString::null, "Charts (*.cht)", this, "file open", "Chart -- File Open" ); if ( !filename.isEmpty() ) load( filename ); else statusBar()->message( "File Open abandoned", 2000 ); } void ChartForm::fileSaveAs() { TQString filename = TQFileDialog::getSaveFileName( TQString::null, "Charts (*.cht)", this, "file save as", "Chart -- File Save As" ); if ( !filename.isEmpty() ) { int answer = 0; if ( TQFile::exists( filename ) ) answer = TQMessageBox::warning( this, "Chart -- Overwrite File", TQString( "Overwrite\n\'%1\'?" ). arg( filename ), "&Yes", "&No", TQString::null, 1, 1 ); if ( answer == 0 ) { m_filename = filename; updateRecentFiles( filename ); fileSave(); return; } } statusBar()->message( "Saving abandoned", 2000 ); } void ChartForm::fileOpenRecent( int index ) { if ( !okToClear() ) return; load( m_recentFiles[index] ); } void ChartForm::updateRecentFiles( const TQString& filename ) { if ( m_recentFiles.find( filename ) != m_recentFiles.end() ) return; m_recentFiles.push_back( filename ); if ( m_recentFiles.count() > MAX_RECENTFILES ) m_recentFiles.pop_front(); updateRecentFilesMenu(); } void ChartForm::updateRecentFilesMenu() { for ( int i = 0; i < MAX_RECENTFILES; ++i ) { if ( fileMenu->findItem( i ) ) fileMenu->removeItem( i ); if ( i < int(m_recentFiles.count()) ) fileMenu->insertItem( TQString( "&%1 %2" ). arg( i + 1 ).arg( m_recentFiles[i] ), this, TQ_SLOT( fileOpenRecent(int) ), 0, i ); } } void ChartForm::fileQuit() { if ( okToClear() ) { saveOptions(); tqApp->exit( 0 ); } } bool ChartForm::okToClear() { if ( m_changed ) { TQString msg; if ( m_filename.isEmpty() ) msg = "Unnamed chart "; else msg = TQString( "Chart '%1'\n" ).arg( m_filename ); msg += "has been changed."; int x = TQMessageBox::information( this, "Chart -- Unsaved Changes", msg, "&Save", "Cancel", "&Abandon", 0, 1 ); switch( x ) { case 0: // Save fileSave(); break; case 1: // Cancel default: return FALSE; case 2: // Abandon break; } } return TRUE; } void ChartForm::saveOptions() { TQSettings settings; settings.insertSearchPath( TQSettings::Windows, WINDOWS_REGISTRY ); settings.writeEntry( APP_KEY + "WindowWidth", width() ); settings.writeEntry( APP_KEY + "WindowHeight", height() ); settings.writeEntry( APP_KEY + "WindowX", x() ); settings.writeEntry( APP_KEY + "WindowY", y() ); settings.writeEntry( APP_KEY + "ChartType", int(m_chartType) ); settings.writeEntry( APP_KEY + "AddValues", int(m_addValues) ); settings.writeEntry( APP_KEY + "Decimals", m_decimalPlaces ); settings.writeEntry( APP_KEY + "Font", m_font.toString() ); for ( int i = 0; i < int(m_recentFiles.count()); ++i ) settings.writeEntry( APP_KEY + "File" + TQString::number( i + 1 ), m_recentFiles[i] ); } void ChartForm::optionsSetData() { SetDataForm *setDataForm = new SetDataForm( &m_elements, m_decimalPlaces, this ); if ( setDataForm->exec() ) { m_changed = TRUE; drawElements(); } delete setDataForm; } void ChartForm::setChartType( ChartType chartType ) { m_chartType = chartType; switch ( m_chartType ) { case PIE: optionsPieChartAction->setOn( TRUE ); break; case VERTICAL_BAR: optionsVerticalBarChartAction->setOn( TRUE ); break; case HORIZONTAL_BAR: optionsHorizontalBarChartAction->setOn( TRUE ); break; } } void ChartForm::updateChartType( TQAction *action ) { if ( action == optionsPieChartAction ) { m_chartType = PIE; } else if ( action == optionsHorizontalBarChartAction ) { m_chartType = HORIZONTAL_BAR; } else if ( action == optionsVerticalBarChartAction ) { m_chartType = VERTICAL_BAR; } drawElements(); } void ChartForm::optionsSetFont() { bool ok; TQFont font = TQFontDialog::getFont( &ok, m_font, this ); if ( ok ) { m_font = font; drawElements(); } } void ChartForm::optionsSetOptions() { OptionsForm *optionsForm = new OptionsForm( this ); optionsForm->chartTypeComboBox->setCurrentItem( m_chartType ); optionsForm->setFont( m_font ); switch ( m_addValues ) { case NO: optionsForm->noRadioButton->setChecked( TRUE ); break; case YES: optionsForm->yesRadioButton->setChecked( TRUE ); break; case AS_PERCENTAGE: optionsForm->asPercentageRadioButton->setChecked( TRUE ); break; } optionsForm->decimalPlacesSpinBox->setValue( m_decimalPlaces ); if ( optionsForm->exec() ) { setChartType( ChartType( optionsForm->chartTypeComboBox->currentItem()) ); m_font = optionsForm->font(); if ( optionsForm->noRadioButton->isChecked() ) m_addValues = NO; else if ( optionsForm->yesRadioButton->isChecked() ) m_addValues = YES; else if ( optionsForm->asPercentageRadioButton->isChecked() ) m_addValues = AS_PERCENTAGE; m_decimalPlaces = optionsForm->decimalPlacesSpinBox->value(); drawElements(); } delete optionsForm; } void ChartForm::helpHelp() { statusBar()->message( "Help is not implemented yet", 2000 ); } void ChartForm::helpAbout() { TQMessageBox::about( this, "Chart -- About", "<center><h1><font color=blue>Chart<font></h1></center>" "<p>Chart your data with <i>chart</i>.</p>" ); } void ChartForm::helpAboutTQt() { TQMessageBox::aboutTQt( this, "Chart -- About TQt" ); }
Main:
#include <ntqapplication.h> #include "chartform.h" int main( int argc, char *argv[] ) { TQApplication app( argc, argv ); TQString filename; if ( app.argc() > 1 ) { filename = app.argv()[1]; if ( !filename.endsWith( ".cht" ) ) filename = TQString::null; } ChartForm *cf = new ChartForm( filename ); app.setMainWidget( cf ); cf->show(); return app.exec(); }
See also Step-by-step Examples.
Copyright © 2007 Trolltech | Trademarks | TQt 3.3.8
|