Prima di cominciare, facciamo notare che in Qt possiamo realizzare solo l'equivalente delle applicazioni Java ma non applet! Il C++, a differenza di Java, di solito non puo' girare all'interno di un browser.Chiariamo brevemente che al momento attuale Linux viene distribuito con due interfacce grafiche alternative e praticamente identiche:Gnome e KDE. Gnome ha alla base GTK+ e KDE invece Qt. Ambedue le interfacce sono servite a costruire programmi molto avanzati che ne mostrano le possibilita' come: Gimp(una specie di Photoshop per Linux) per GTK+ e Konqueror (un browser) per il KDE. Possiamo dire che i due approcci sono equivalenti ed e' questione di gusti se scegliere l'uno o l'altro. L'esperimento CMS al Cern ha scelto per esempio Qt per i suoi programmi grafici.
file ciao.cc
#include <qapplication.h> #include <qlabel.h> int main (int argc, char* argv[]) { QApplication ciao(argc,argv); QLabel* scritta = new QLabel("Ciao a tutti!",0); scritta->resize(120,30); ciao.setMainWidget(scritta); scritta->show(); return ciao.exec(); }Per eseguire questo programma dovreste dare dei comandi di questo tipo:
g++ -o ciao ciao.cc -I$QTDIR/include -L/$QTDIR/lib -lqt ciao
QApplication
e QLabel
. Come Java,
Qt offre una ricca libreria di oggetti .
Il manuale di Qt documenta tutti gli oggetti disponibili.
QApplication
deve essere necessariamente presente in un'unica
copia e serve per gestire gli eventi.Ogni programma Qt deve avere inoltre un "main widget" che viene definito col metodo setMainWidget()
di QApplication
widget
in Qt) perche' ne facilita la gestione automatica.
file MyWidget.cpp
#include <qapplication.h> #include <qpushbutton.h> #include <qlineedit.h> #include <qvbox.h> class MyWidget : public QVBox { public: MyWidget (QWidget *parent=0, const char *name=0); }; MyWidget::MyWidget(QWidget *parent, const char *name) : QVBox(parent,name) { QPushButton *b1 = new QPushButton("This is button 1",this); QPushButton *b2 = new QPushButton("This is button 2",this); QLineEdit *t = new QLineEdit("This is a LineEdit",this); } int main (int argc, char* argv[]) { QApplication a(argc,argv); MyWidget w; a.setMainWidget(&w); w.show(); return a.exec(); }
QWidget
. In particolare QVBox viene qui usato perche' permette di aggiungere nuovi oggetti al suo
interno "alla rinfusa".
QVBOX
this
file MyWidget1.cpp
#include <qapplication.h> #include <qpushbutton.h> #include <qlineedit.h> #include <qlayout.h> class MyWidget : public QWidget { public: MyWidget (QWidget *parent=0, const char *name=0); }; MyWidget::MyWidget(QWidget *parent, const char *name) : QWidget(parent,name) { QPushButton *b1 = new QPushButton("This is button 1",this); QPushButton *b2 = new QPushButton("This is button 2",this); QLineEdit *t = new QLineEdit("This is a LineEdit",this); QGridLayout *grid = new QGridLayout( this, 2, 2, 10 ); grid->addWidget( b1, 0, 0 ); grid->addWidget( b2, 1, 0 ); grid->addWidget( t, 1, 1 ); } int main (int argc, char* argv[]) { QApplication a(argc,argv); MyWidget w; w.setGeometry(100,100,200,100); a.setMainWidget(&w); w.show(); return a.exec(); }
file MyButton.h
#include <qapplication.h> #include <qpushbutton.h> #include <qlineedit.h> #include <qlayout.h> # include <iostream> # include <string> class MyWidget : public QWidget { Q_OBJECT public: MyWidget (QWidget *parent=0, const char *name=0); signals: public slots: void scrivi1(); void scrivi2(); };
file MyButton.cpp
#include "MyButton.h" MyWidget::MyWidget(QWidget *parent, const char *name) : QWidget(parent,name) { QPushButton *b1 = new QPushButton("This is button 1",this); QPushButton *b2 = new QPushButton("This is button 2",this); QLineEdit *t = new QLineEdit("This is a LineEdit",this); QGridLayout *grid = new QGridLayout( this, 2, 2, 10 ); grid->addWidget( b1, 0, 0 ); grid->addWidget( b2, 1, 0 ); grid->addWidget( t, 1, 1 ); QObject::connect(b1, SIGNAL(clicked()),this,SLOT(scrivi1())); QObject::connect(b2, SIGNAL(clicked()),this,SLOT(scrivi2())); } void MyWidget::scrivi1(){cout << "Bottone 1 cliccato!" << endl;} void MyWidget::scrivi2(){cout << "Bottone 2 cliccato!" << endl;} int main (int argc, char* argv[]) { QApplication a(argc,argv); MyWidget w; w.setGeometry(100,100,200,100); a.setMainWidget(&w); w.show(); return a.exec(); }Per eseguire questo programma dovreste dare i seguenti comandi:
$QTDIR/bin/moc -o MyButton_moc.cc MyButton.h g++ -o MyButton MyButton.cpp MyButton_moc.cc -I$QTDIR/include -L$QTDIR/lib -lqt ./MyButton
moc
fornito con Qt che provvede a convertire alcune macro come
"QOBJECT" in linguaggio C++ standard.(moc
sta per meta object compiler)
file MyButton.h
#include <qapplication.h> #include <qpushbutton.h> #include <qlineedit.h> #include <qlayout.h> #include <qslider.h> # include <iostream> # include <string> #include "MyCanvas.h" class MyWidget : public QWidget { Q_OBJECT public: MyWidget (QWidget *parent=0, const char *name=0); signals: public slots: private: QSlider *slider; MyCanvas *canvas; };
file MyButton.cpp
#include "MyButton.h" MyWidget::MyWidget(QWidget *parent, const char *name) : QWidget(parent,name) { slider = new QSlider(Horizontal,this,"slider"); slider->setRange(0,99); slider->setValue(0); canvas = new MyCanvas(this,"MyCanvas"); QGridLayout *grid = new QGridLayout( this, 2, 1, 10 ); grid->addWidget( slider, 0, 0 ); grid->addWidget( canvas, 1, 0 ); QObject::connect(slider, SIGNAL(valueChanged(int)),canvas,SLOT(draw(int))); } int main (int argc, char* argv[]) { QApplication a(argc,argv); MyWidget w; w.setGeometry(100,100,200,100); a.setMainWidget(&w); w.show(); return a.exec(); }
file MyCanvas.h
#ifndef MYCANVAS_H #define MYCANVAS_H #include <qwidget.h> class MyCanvas : public QWidget { Q_OBJECT public: MyCanvas (QWidget *parent=0, const char *name=0); signals: public slots: void draw(int size); protected: void paintEvent(QPaintEvent *); private: int size; }; #endif
file MyCanvas.cpp
#include "MyCanvas.h" #include <qpainter.h> MyCanvas::MyCanvas(QWidget *parent, const char *name) : QWidget(parent,name) { size=1; setPalette( QPalette( QColor( 250, 250, 200) ) ); } void MyCanvas::draw(int s){ size = s; repaint(); } void MyCanvas::paintEvent( QPaintEvent * ) { QPainter p( this ); p.drawRect( 100, 100, size,size ); }
QSlider
e un altro qwidget che
funziona da "canvas" per fare un disegno.
paint
di Java e' la paintEvent
repaint
QPainter
in Qt.
file MyButton.h
#include <qapplication.h> #include <qpushbutton.h> #include <qmainwindow.h> #include <qlineedit.h> #include <qlayout.h> #include <qslider.h> # include <iostream> # include <string> #include "MyCanvas.h" class MyWidget : public QWidget { Q_OBJECT public: MyWidget (QWidget *parent=0, const char *name=0); signals: void mysignal(int,string); public slots: void myslot(int); private: QSlider *slider; MyCanvas *canvas; string s; int size; }; class MainWindow : public QMainWindow { public: MainWindow (QWidget *parent=0, const char *name=0); private: MyWidget *mw; };
file MyButton.cpp
#include "MyButton.h" MainWindow::MainWindow(QWidget *parent, const char *name) : QMainWindow(parent,name) { mw = new MyWidget(this,"MyWidget"); setCentralWidget(mw); } MyWidget::MyWidget(QWidget *parent, const char *name) : QWidget(parent,name) { slider = new QSlider(Horizontal,this,"slider"); slider->setRange(0,99); slider->setValue(0); canvas = new MyCanvas(this,"MyCanvas"); QGridLayout *grid = new QGridLayout( this, 2, 1, 10 ); grid->addWidget( slider, 0, 0 ); grid->addWidget( canvas, 1, 0 ); s = "Pinco Pallino"; QObject::connect(slider, SIGNAL(valueChanged(int)),this,SLOT(myslot(int))); QObject::connect(this, SIGNAL(mysignal(int,string)),canvas,SLOT(draw(int,string))); } void MyWidget::myslot(int x){ size = x; emit mysignal(size,s); } int main (int argc, char* argv[]) { QApplication a(argc,argv); MainWindow *w = new MainWindow();; w->setCaption("Quadrato di dimensioni variabili"); w->setGeometry(100,100,200,100); w->show(); return a.exec(); }
file MyCanvas.h
#ifndef MYCANVAS_H #define MYCANVAS_H #include <qwidget.h> #include <string> class MyCanvas : public QWidget { Q_OBJECT public: MyCanvas (QWidget *parent=0, const char *name=0); signals: public slots: void draw(int size,string s); protected: void paintEvent(QPaintEvent *); private: int size; string nome; }; #endif
file MyCanvas.cpp
#include "MyCanvas.h" #include <qpainter.h> #include <qstring.h> MyCanvas::MyCanvas(QWidget *parent, const char *name) : QWidget(parent,name) { size=1; setPalette( QPalette( QColor( 250, 250, 200) ) ); } void MyCanvas::draw(int s,string str){ size = s; nome=str; repaint(); } void MyCanvas::paintEvent( QPaintEvent * ) { const char *c = nome.c_str(); QString qnome(c) ; QPainter p( this ); p.drawRect( 100, 100, size,size ); p.drawText(10,10,qnome); }
myslot
e un nuovo segnale
mysignal
draw
facciamo il collegamento passando attraverso myslot e mysignal.
MyCanvas
emit
permette di lanciare un segnale a programma.
# Makefile for Simple X11 OpenGL program. GLDIR = /lhcxx/specific/redhat61/Mesa/3.2 CPP = g++ LIBDIR = -L$(GLDIR)/lib -L/usr/lib -L/usr/X11R6/lib INCDIR = -I$(GLDIR)/include -I/usr/include -I/usr/X11R6/include CFLAGS = $(INCDIR) $(LIBDIR) XLIBS = -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE GL_LIBS = -lglut -lGLU -lGL -lm PROGS = simple_x11 ##### RULES ##### .cpp: *.cpp $(CPP) $(CFLAGS) $< $(GL_LIBS) -o $@ ##### TARGETS ###### default: $(PROGS)
iview
potete,con OpenInventor, creare e visualizzare una scena 3D scrivendo un file ASCII che descrive la scena senza bisogno di scrivere programmi!
SoXtRenderArea
nella quale inseriamo una semplice scena
con una forma 3D SoCone
,di un materiale SoMaterial
illuminata da una SoDirectionalLight
e vista da una telecamera SoPerspectiveCamera
. I 4 nodi vengono tutti collegati a un oggetto SoSeparator
che serve a creare la struttura.
#include <math.h> #include <Inventor/Xt/SoXt.h> #include <Inventor/Xt/SoXtRenderArea.h> #include <Inventor/nodes/SoCone.h> #include <Inventor/nodes/SoDirectionalLight.h> #include <Inventor/nodes/SoMaterial.h> #include <Inventor/nodes/SoPerspectiveCamera.h> #include <Inventor/nodes/SoSeparator.h> void main(int , char **argv) { // Initialize Inventor. This returns a main window to use. // If unsuccessful, exit. Widget myWindow = SoXt::init(argv[0]); // pass the app name if (myWindow == NULL) exit(1); SoSeparator *root = new SoSeparator; SoPerspectiveCamera *myCamera = new SoPerspectiveCamera; SoMaterial *myMaterial = new SoMaterial; root->ref(); root->addChild(myCamera); root->addChild(new SoDirectionalLight); myMaterial->diffuseColor.setValue(0.0, 1.0, 0.0); //Green root->addChild(myMaterial); root->addChild(new SoCone); // Create a renderArea in which to see our scene graph. // The render area will appear within the main window. SoXtRenderArea *myRenderArea = new SoXtRenderArea(myWindow); // Make myCamera see everything. myCamera->viewAll(root, myRenderArea->getViewportRegion()); // Put our scene in myRenderArea, change the title myRenderArea->setSceneGraph(root); myRenderArea->setTitle("Hello Cone"); myRenderArea->show(); SoXt::show(myWindow); // Display main window SoXt::mainLoop(); // Main Inventor event loop }Se invece di usare la
SoXtRenderArea
usiamo una SoXtExaminerViewer
abbiamo tutta una serie di gadget che ci permettono di manipolare la scena
a nostro piacimento.
file Prog2.cxx
#include <Inventor/SoDB.h> #include <Inventor/SoInput.h> #include <Inventor/Xt/SoXt.h> #include <Inventor/Xt/viewers/SoXtExaminerViewer.h> #include <Inventor/nodes/SoSeparator.h> #include <math.h> #include <Inventor/nodes/SoCone.h> #include <Inventor/nodes/SoDirectionalLight.h> #include <Inventor/nodes/SoMaterial.h> void main(int argc, char **argv) { // Initialize Inventor and Xt Widget myWindow = SoXt::init(argv[0]); if (myWindow == NULL) exit(1); SoSeparator *root = new SoSeparator; SoMaterial *myMaterial = new SoMaterial; root->ref(); root->addChild(new SoDirectionalLight); myMaterial->diffuseColor.setValue(0.0, 1.0, 0.0); //Green root->addChild(myMaterial); root->addChild(new SoCone); // Create a viewer SoXtExaminerViewer *myViewer = new SoXtExaminerViewer(myWindow); // attach and show viewer myViewer->setSceneGraph(root); myViewer->setTitle("File Reader"); myViewer->show(); // Loop forever SoXt::show(myWindow); SoXt::mainLoop(); }Il toolkit di OpenInventor contiene moltissimi oggetti grafici (tutti col nome che comincia con So) e questi possono essere estesi.
#Inventor V2.0 ascii Separator { SpotLight { color 0.6 0.3 0.3 location 5 10 0 direction -1 -1 0 } Material { diffuseColor 0.8 0.0 0.8 specularColor 0.3 0.0 0.3 ambientColor 0.2 0.0 0.2 } Transform { translation -1.0 1.5 1.0 } Cone {} }Ed ecco come appare la scena in un visualizzatore che l'ha letta dal file Ascii.
file casa.iv
#Inventor V2.1 ascii DEF RPC_ Separator { Material { ambientColor 0 0 0 diffuseColor 0 0 0 specularColor 0.622 0.622 0.622 emissiveColor 0 1 1 shininess 0.121 transparency 0 } ShapeHints { shapeType SOLID } Coordinate3 { point [ 0. 0. 13.5 , 4. 0. 13.5 , 4. 3. 13.5, 2. 4. 13.5, 0. 3. 13.5, 0. 0. 7.5, 4. 0. 7.5, 4. 3. 7.5, 2. 4. 7.5, 0. 3. 7.5, 1. 0. 13.5, 2. 0. 13.5, 2. 2. 13.5, 1. 2. 13.5] } IndexedFaceSet { coordIndex [ 0 , 1 , 2, 3, 4, -1 ,5,6,7,8,9, -1 , 1,6,7,2 , -1 , 5,0,4,9, -1 , 4,3,8,9 , -1 , 3,2,7,8, -1 ] } DrawStyle { linePattern 0xffff } IndexedLineSet { coordIndex [ 0 , 1 , 2, 3, 4, -1 ,5,6,7,8,9, -1 , 1,6,7,2 , -1 , 5,0,4,9, -1 , 4,3,8,9 , -1 , 3,2,7,8, -1,10,11,12,13,-1 ] } }
file casa2.iv
#Inventor V2.1 ascii Separator { SpotLight { color 0.6 0.3 0.3 location 5 10 0 direction -1 -1 0 } Material { ambientColor 0.2 0 0.2 diffuseColor 0.8 0 0.8 specularColor 0.3 0.0 0.3 emissiveColor 0 1 1 shininess 0.121 transparency 0 } ShapeHints { shapeType SOLID } Coordinate3 { point [ 0. 0. 13.5 , 4. 0. 13.5 , 4. 3. 13.5, 2. 4. 13.5, 0. 3. 13.5, 0. 0. 7.5, 4. 0. 7.5, 4. 3. 7.5, 2. 4. 7.5, 0. 3. 7.5, 1. 0. 13.5, 2. 0. 13.5, 2. 2. 13.5, 1. 2. 13.5] } IndexedFaceSet { coordIndex [ 0 , 1 , 2, 3, 4, -1 ,5,6,7,8,9, -1 , 1,6,7,2 , -1 , 5,0,4,9, -1 , 4,3,8,9 , -1 , 3,2,7,8, -1 ] } DrawStyle { linePattern 0xffff } IndexedLineSet { coordIndex [ 0 , 1 , 2, 3, 4, -1 ,5,6,7,8,9, -1 , 1,6,7,2 , -1 , 5,0,4,9, -1 , 4,3,8,9 , -1 , 3,2,7,8, -1,10,11,12,13,-1 ] } ResetTransform { } Transform { translation 1.307 -7.049 -5.3295 rotation -1.09278e-08 -1.09278e-08 1 3.14159 scaleFactor 1 1 1 scaleOrientation -0.434027 0.17978 -0.88278 0.877436 } Coordinate3 { point [ 0. 0. 13.5 , 4. 0. 13.5 , 4. 3. 13.5, 2. 4. 13.5, 0. 3. 13.5, 0. 0. 7.5, 4. 0. 7.5, 4. 3. 7.5, 2. 4. 7.5, 0. 3. 7.5, 1. 0. 13.5, 2. 0. 13.5, 2. 2. 13.5, 1. 2. 13.5] } IndexedFaceSet { coordIndex [ 0 , 1 , 2, 3, 4, -1 ,5,6,7,8,9, -1 , 1,6,7,2 , -1 , 5,0,4,9, -1 , 4,3,8,9 , -1 , 3,2,7,8, -1 ] } DrawStyle { linePattern 0xffff } IndexedLineSet { coordIndex [ 0 , 1 , 2, 3, 4, -1 ,5,6,7,8,9, -1 , 1,6,7,2 , -1 , 5,0,4,9, -1 , 4,3,8,9 , -1 , 3,2,7,8, -1,10,11,12,13,-1 ] } }
file Prog1.cpp
#include <iostream.h> #include <GL/glut.h> #include <stdio.h> #include <stdlib.h> GLfloat casa[14][3]={ {0.,0.,13.5}, {4.,0.,13.5}, {4., 3., 13.5}, {2.,4.,13.5}, {0.,3.,13.5}, {0.,0.,7.5}, {4.,0.,7.5}, {4.,3.,7.5}, {2.,4.,7.5}, {0.,3.,7.5}, {1.,0.,13.5}, {2.,0.,13.5}, {2.,2.,13.5}, {1.,2.,13.5} }; int faceRefs[6][5]= { {0, 1, 2, 3,4}, {5, 9, 8, 7, 6}, {1, 6, 7, 2,-1}, {5, 0, 4, 9,-1}, {4, 3, 8, 9,-1}, {3, 2, 7, 8,-1} }; void buildCasaList(void) { GLfloat x, y, z; glNewList(1, GL_COMPILE); for (int i=0; i<6; i++) { glBegin(GL_POLYGON); x=casa[faceRefs[i][0]][0]; y=casa[faceRefs[i][0]][1]; z=casa[faceRefs[i][0]][2]; glVertex3f(x, y, z); x=casa[faceRefs[i][1]][0]; y=casa[faceRefs[i][1]][1]; z=casa[faceRefs[i][1]][2]; glVertex3f(x, y, z); x=casa[faceRefs[i][2]][0]; y=casa[faceRefs[i][2]][1]; z=casa[faceRefs[i][2]][2]; glVertex3f(x, y, z); x=casa[faceRefs[i][3]][0]; y=casa[faceRefs[i][3]][1]; z=casa[faceRefs[i][3]][2]; glVertex3f(x, y, z); if(faceRefs[i][4] != -1){ x=casa[faceRefs[i][4]][0]; y=casa[faceRefs[i][4]][1]; z=casa[faceRefs[i][4]][2]; glVertex3f(x, y, z); } glEnd(); } glColor3f(1.0f,0.0f,0.0f); glBegin(GL_QUADS); x=casa[10][0]; y=casa[10][1]; z=casa[10][2]; glVertex3f(x,y,z); x=casa[11][0]; y=casa[11][1]; z=casa[11][2]; glVertex3f(x,y,z); x=casa[12][0]; y=casa[12][1]; z=casa[12][2]; glVertex3f(x,y,z); x=casa[13][0]; y=casa[13][1]; z=casa[13][2]; glVertex3f(x,y,z); glEnd(); glEndList(); } void renderScene(void) { glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.0, 0.0, 1.0); glCallList(1); glFlush(); glutSwapBuffers(); } void reshapeFunction(int width, int height) { glViewport(0, 0, (GLint)width, (GLint)height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-20.5, 20.5, -2.5, 15.5, 50.0, -50.0); glMatrixMode(GL_MODELVIEW); } void idleFunction(void) { glRotatef(0.1f, 0.0, 1.0, 1.0); renderScene(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(200, 200); glutInitWindowPosition (100, 100); glutCreateWindow("Casa"); glutReshapeFunc(reshapeFunction); buildCasaList(); glutDisplayFunc(renderScene); glutIdleFunc(idleFunction); glutMainLoop(); return 0; }
file MyCube.h
#include <qapplication.h> #include <qpushbutton.h> #include <qlineedit.h> #include <qlayout.h> #include <qslider.h> # include <iostream> # include <string> # include "My3DCanvas.h" class MyWidget : public QWidget { Q_OBJECT public: MyWidget (QWidget *parent=0, const char *name=0); signals: public slots: private: QSlider *slider; My3DCanvas *canvas; };
file MyCube.cpp
#include "MyCube.h" MyWidget::MyWidget(QWidget *parent, const char *name) : QWidget(parent,name) { slider = new QSlider(Horizontal,this,"slider"); slider->setRange(0,99); slider->setValue(0); QGridLayout *grid = new QGridLayout( this, 2, 1, 10 ); My3DCanvas *canvas = new My3DCanvas(this,"cube"); grid->addWidget( slider, 0, 0 ); grid->addWidget( canvas, 1, 0 ); QObject::connect(slider, SIGNAL(valueChanged(int)),canvas,SLOT(draw(int))); } int main (int argc, char* argv[]) { QApplication a(argc,argv); MyWidget w; w.setGeometry(100,100,400,400); a.setMainWidget(&w); w.show(); return a.exec(); }
file My3DCanvas.h
#ifndef MY3DCANVAS_H #define MY3DCANVAS_H #include <qwidget.h> #include <Inventor/Qt/viewers/SoQtExaminerViewer.h> #include <Inventor/nodes/SoSeparator.h> #include <Inventor/nodes/SoCube.h> class My3DCanvas : public QWidget { Q_OBJECT public: My3DCanvas (QWidget *parent=0, const char *name=0); signals: public slots: void draw(int size); private: int size; SoQtExaminerViewer *eviewer; SoSeparator *root; SoCube *cube1; }; #endif
file My3DCanvas.cpp
#include "My3DCanvas.h" #include <Inventor/Qt/SoQt.h> #include <Inventor/Qt/viewers/SoQtExaminerViewer.h> #include <Inventor/nodes/SoCube.h> #include <Inventor/nodes/SoSeparator.h> #include <Inventor/nodes/SoDirectionalLight.h> #include <Inventor/nodes/SoMaterial.h> My3DCanvas::My3DCanvas(QWidget *parent, const char *name) : QWidget(parent,name) { size=1; SoQt::init(this); eviewer = new SoQtExaminerViewer(this); root = new SoSeparator; SoCube *mycube = new SoCube; SoMaterial *myMaterial1 = new SoMaterial; mycube->width = 400; mycube->height =400; mycube->depth =400 ; myMaterial1->diffuseColor.setValue(1.0, 0.0, 0.0); myMaterial1->transparency = 1.0; root->addChild(myMaterial1); root->addChild(mycube); SoMaterial *myMaterial = new SoMaterial; root->ref(); root->addChild(new SoDirectionalLight); myMaterial->diffuseColor.setValue(0.0, 1.0, 0.0); //Green root->addChild(myMaterial); cube1 = new SoCube; cube1->width = size; cube1->height =size; cube1->depth =size ; root->addChild(cube1); eviewer->setSceneGraph(root); eviewer->show(); } void My3DCanvas::draw(int s){ size = s; root->enableNotify(FALSE); cube1->width = size; cube1->height =size; cube1->depth =size ; root->enableNotify(TRUE); root->touch(); }
SoQtExaminerViewer
. Questo funziona all'incirca come SoXtExaminer del Programma 7.
SoQt::init(this);
necessaria perche' tutto funzioni.
draw()
la tecnica usata per modificare il disegno disabilitando il Notify
(che produce un'aggiornamento automatico del disegno).Quindi si procede a modificare il grafo. Alla fine si riabilita il Notify e con touch si procede a far
ridisegnare il tutto.