Introduction to C C Lecture 8 GUI QT

  • Slides: 45
Download presentation
Introduction to C & C++ Lecture 8 – GUI -- QT JJCAO

Introduction to C & C++ Lecture 8 – GUI -- QT JJCAO

Hello world • L 1: The ideas behind Qt and live demo of Qt

Hello world • L 1: The ideas behind Qt and live demo of Qt in Education #include <QApplication> #include <QLabel> int main( int argc, char **argv ) { QApplication app( argc, argv ); QLabel l( "Hello World!" ); l. show(); return app. exec(); }

Scribble – a “Complete” app • • Subclassing QMain. Window Creating Menus and Toolbars

Scribble – a “Complete” app • • Subclassing QMain. Window Creating Menus and Toolbars Implementing the File Menu Using Dialogs Splash Screens Storing Settings Status Bar A live demo!

Create an Qt Application XScribble

Create an Qt Application XScribble

Subclassing QMain. Window

Subclassing QMain. Window

Creating Menus Double click “xscribble. ui” in the “Solution Explorer” Press Return or Enter

Creating Menus Double click “xscribble. ui” in the “Solution Explorer” Press Return or Enter to accept the new text, or press Escape to reject it.

Add Resources

Add Resources

Add Icon to Menu Item / Action

Add Icon to Menu Item / Action

Creating Toolbar Drag and Drop

Creating Toolbar Drag and Drop

Behind the Designer

Behind the Designer

Implementing the File Menu “action. Save” --Signals & Slots public slots: If the slot

Implementing the File Menu “action. Save” --Signals & Slots public slots: If the slot you wanted is a default slot of the recever

More Actions

More Actions

Implement Action - action. Line enum Draw. Flag { NONE, LINE, CIRCLE }; public

Implement Action - action. Line enum Draw. Flag { NONE, LINE, CIRCLE }; public slots: void save. File(); void flag. Line(){m_draw. Flag=LINE; } void flag. Circle(){ m_draw. Flag=CIRCLE; } connect( ui. action. Line, SIGNAL(triggered()), this, SLOT(flag. Line()) ); connect( ui. action. Circle, SIGNAL(triggered()), this, SLOT(flag. Circle()) );

Current GUI

Current GUI

Where to Scribble?

Where to Scribble?

Promotion

Promotion

Scribble!! protected: void mouse. Press. Event(QMouse. Event *event); void mouse. Move. Event(QMouse. Event *event);

Scribble!! protected: void mouse. Press. Event(QMouse. Event *event); void mouse. Move. Event(QMouse. Event *event); void mouse. Release. Event(QMouse. Event *event); void paint. Event(QPaint. Event *event);

Mouse Events void Scribble. Area: : mouse. Press. Event(QMouse. Event *event) { if (event->button()

Mouse Events void Scribble. Area: : mouse. Press. Event(QMouse. Event *event) { if (event->button() == Qt: : Left. Button) { m_last. Point = event->pos(); } } void Scribble. Area: : mouse. Move. Event(QMouse. Event *event) { if ((event->buttons() & Qt: : Left. Button) ) { switch (m_draw. Flag) { case FREE: draw. Free( event->pos()); break; } } }

draw. Free( const QPoint& pt) void Scribble. Area: : paint. Event(QPaint. Event *event) {

draw. Free( const QPoint& pt) void Scribble. Area: : paint. Event(QPaint. Event *event) { QPainter painter(this); QRect dirty. Rect = event->rect(); // Local re-paint to decrease flickering painter. draw. Image(dirty. Rect, m_image, dirty. Rect); } void Scribble. Area: : draw. Free(const QPoint& pt) { QPainter painter(&m_image); painter. set. Pen(QPen(m_pen. Color, m_pen. Width, Qt: : Solid. Line, Qt: : Round. Cap, Qt: : Round. Join)); painter. draw. Line(m_last. Point, pt); m_last. Point = pt; }

The m_image is not initialized properly void Scribble. Area: : resize. Event(QResize. Event *event){

The m_image is not initialized properly void Scribble. Area: : resize. Event(QResize. Event *event){ if (width() > m_image. width() || height() > m_image. height()) { int new. Width = q. Max(width() + 128, m_image. width()); int new. Height = q. Max(height() + 128, m_image. height()); resize. Image(&m_image, QSize(new. Width, new. Height)); update(); } QWidget: : resize. Event(event); } void Scribble. Area: : resize. Image(QImage *image, const QSize &new. Size){ if (image->size() == new. Size) return; QImage new. Image(new. Size, QImage: : Format_RGB 32); new. Image. fill(q. Rgb(255, 255)); QPainter painter(&new. Image); painter. draw. Image(QPoint(0, 0), *image); *image = new. Image; }

Try! But nothing happens? • However if you switch the screen back from minimization,

Try! But nothing happens? • However if you switch the screen back from minimization, you find what you drew. • What happened? void Scribble. Area: : draw. Free(const QPoint& pt) { QPainter painter(&m_image); painter. set. Pen(QPen(m_pen. Color, m_pen. Width, Qt: : Solid. Line, Qt: : Round. Cap, Qt: : Round. Join)); painter. draw. Line(m_last. Point, pt); // update what you just drew int rad = (m_pen. Width / 2) + 2; update(QRect(m_last. Point, pt). normalized(). adjusted(-rad, +rad, +rad)); m_last. Point = pt; }

Finally worked, but? action. Free. Hand->set. Checkable(true); action. Free. Hand->set. Checked(true);

Finally worked, but? action. Free. Hand->set. Checkable(true); action. Free. Hand->set. Checked(true);

More • • Shortcut key Using Dialogs Splash Screens Storing Settings

More • • Shortcut key Using Dialogs Splash Screens Storing Settings

Shortcut key

Shortcut key

Key & Action

Key & Action

Setting the color of the pen Scribble. Area: : Scribble. Area(QWidget *parent) : QWidget(parent),

Setting the color of the pen Scribble. Area: : Scribble. Area(QWidget *parent) : QWidget(parent), m_draw. Flag(FREE) { ui. setup. Ui(this); set. Attribute(Qt: : WA_Static. Contents); } m_pen = QPen(Qt: : blue, 1, Qt: : Solid. Line, Qt: : Round. Cap, Qt: : Round. Join);

Setting the color of the pen void Scribble. Area: : set. Pen. Color() {

Setting the color of the pen void Scribble. Area: : set. Pen. Color() { QColor old. Color = m_pen. color(); QColor color = QColor. Dialog: : get. Color(old. Color, this); m_pen. set. Color(color); }

Open an Image 1 XScribble: : XScribble(QWidget *parent, Qt: : WFlags flags) { …

Open an Image 1 XScribble: : XScribble(QWidget *parent, Qt: : WFlags flags) { … connect( ui. action. Open, SIGNAL(triggered()), this, SLOT(open. File())); … } void XScribble: : open. File(){ if (maybe. Save()) { QString file. Name = QFile. Dialog: : get. Open. File. Name(this, tr("Open File"), QDir: : current. Path()); if (!file. Name. is. Empty()) ui. central. Widget->open. Image(file. Name); } }

Open an Image 2 bool XScribble: : maybe. Save() { if (ui. central. Widget->is.

Open an Image 2 bool XScribble: : maybe. Save() { if (ui. central. Widget->is. Modified()) { QMessage. Box: : Standard. Button ret; ret = QMessage. Box: : warning(this, tr("Scribble"), tr("The image has been modified. n" "Do you want to save your changes? "), QMessage. Box: : Save | QMessage. Box: : Discard| QMessage. Box: : Cancel); if (ret == QMessage. Box: : Save) { return save. File("png"); } else if (ret == QMessage. Box: : Cancel) { return false; } } return true; }

Open an Image 3 bool Scribble. Area: : open. Image(const QString &file. Name) {

Open an Image 3 bool Scribble. Area: : open. Image(const QString &file. Name) { QImage loaded. Image; if (!loaded. Image. load(file. Name)) return false; // union of loaded. Image. size() & Scribble. Area's size. QSize new. Size = loaded. Image. size(). expanded. To(size()); resize. Image(&loaded. Image, new. Size); m_image = loaded. Image; m_modified = false; update(); return true; }

Save Your Scribble 1 void XScribble: : create. Actions(){ connect( ui. action. Open, SIGNAL(triggered()),

Save Your Scribble 1 void XScribble: : create. Actions(){ connect( ui. action. Open, SIGNAL(triggered()), this, SLOT(open())); foreach (QByte. Array format, QImage. Writer: : supported. Image. Formats()) { QString text = tr("%1. . . "). arg(QString(format). to. Upper()); QAction *action = new QAction(text, this); action->set. Data(format); connect(action, SIGNAL(triggered()), this, SLOT(save())); m_save. As. Acts. append(action); } … } QList<QAction *> m_save. As. Acts;

Save Your Scribble 2 void XScribble: : create. Menus() { m_save. As. Menu =

Save Your Scribble 2 void XScribble: : create. Menus() { m_save. As. Menu = new QMenu(tr("&Save As"), this); foreach (QAction *action, m_save. As. Acts) m_save. As. Menu->add. Action(action); ui. menu. File->add. Menu(m_save. As. Menu); // menu. File is Qmenu* } void XScribble: : save() { QAction *action = qobject_cast<QAction *>(sender()); QByte. Array file. Format = action->data(). to. Byte. Array(); save. File(file. Format); }

Save Your Scribble 3 bool XScribble: : save. File(const QByte. Array &file. Format) {

Save Your Scribble 3 bool XScribble: : save. File(const QByte. Array &file. Format) { QString initial. Path = QDir: : current. Path() + "/untitled. " + file. Format; QString file. Name = QFile. Dialog: : get. Save. File. Name(this, tr("Save As"), initial. Path, tr("%1 Files (*. %2); ; All Files (*)") . arg(QString(file. Format. to. Upper())) . arg(QString(file. Format))); if (file. Name. is. Empty()) { return false; } else { return ui. central. Widget->save. Image(file. Name, file. Format); } }

Save Your Scribble 4 bool Scribble. Area: : save. Image(const QString &file. Name, const

Save Your Scribble 4 bool Scribble. Area: : save. Image(const QString &file. Name, const char *file. Format) { if (m_image. save(file. Name, file. Format)) { m_modified = false; return true; } else { return false; } }

Splash Screens Add splash. png into the resource by QT Designer int main(int argc,

Splash Screens Add splash. png into the resource by QT Designer int main(int argc, char *argv[]){ QApplication a(argc, argv); QPixmap pixmap(": /XScribble/Resources/splash. png"); QSplash. Screen *splash = new QSplash. Screen(pixmap); splash->show(); splash->show. Message("Loaded modules"); q. App->process. Events(); splash->show. Message("Established connections"); q. App->process. Events(); } XScribble w; w. show(); return a. exec();

Storing Settings – read settings void XScribble: : read. Settings() { QSettings settings("Ability Co.

Storing Settings – read settings void XScribble: : read. Settings() { QSettings settings("Ability Co. Ltd. ", "XScribble"); QRect rect = settings. value("geometry", QRect(200, 400, 400)). to. Rect(); move(rect. top. Left()); resize(rect. size()); m_recent. Files=settings. value("recent. Files"). to. String. List(); update. Recent. File. Actions(); } XScribble: : XScribble(QWidget *parent, Qt: : WFlags flags): QMain. Window(parent, flags){ ui. setup. Ui(this); create. Actions(); create. Menus(); read. Settings(); }

bool is. Not. Exists(const QString& elem) //functor { bool result = QFile: : exists(elem);

bool is. Not. Exists(const QString& elem) //functor { bool result = QFile: : exists(elem); return !result; } void XScribble: : update. Recent. File. Actions() { m_recent. Files. erase( std: : remove_if(m_recent. Files. begin(), m_recent. Files. end(), is. Not. Exists), m_recent. Files. end() ); for (int j = 0; j < Max. Recent. Files; ++j) { if (j < m_recent. Files. count()) { QString text = tr("&%1 %2") . arg(j+1). arg(QFile. Info( m_recent. Files[j] ). file. Name()); m_recent. File. Actions[j]->set. Text(text); m_recent. File. Actions[j]->set. Data(m_recent. Files[j]); m_recent. File. Actions[j]->set. Visible(true); } else { m_recent. File. Actions[j]->set. Visible(false); } } m_separator. Action->set. Visible(!m_recent. Files. is. Empty()); }

void XScribble: : open. Recent. File(){ if (maybe. Save()) { QAction *action = qobject_cast<QAction

void XScribble: : open. Recent. File(){ if (maybe. Save()) { QAction *action = qobject_cast<QAction *>(sender()); if (action) { QString file. Name(action->data(). to. String()); ui. central. Widget->open. Image(file. Name); void XScribble: : open(){ … m_recent. Files. remove. All(file. Name); . . . } m_recent. Files. remove. All(file. Name); m_recent. Files. prepend(file. Name); update. Recent. File. Actions(); set. Window. Title(tr("%1[*] - %2"). arg(QFile. Info(file. Name). file. Name()). arg(tr("Scribble"))); } } } void XScribble: : create. Actions(){ … for (int i = 0; i < Max. Recent. Files; ++i) { m_recent. File. Actions[i] = new QAction(this); m_recent. File. Actions[i]->set. Visible(false); connect (m_recent. File. Actions[i], SIGNAL(triggered()), this, SLOT(open. Recent. File())); } … }

Storing Settings – write settings protected: void close. Event(QClose. Event *event); // overriding 覆盖

Storing Settings – write settings protected: void close. Event(QClose. Event *event); // overriding 覆盖 void XScribble: : close. Event(QClose. Event *event){ if (maybe. Save()) { write. Settings(); event->accept(); } else { event->ignore(); } } void XScribble: : write. Settings(){ QSettings settings("Ability Co. Ltd. ", "XScribble"); settings. set. Value("geometry", geometry()); settings. set. Value("recent. Files", m_recent. Files); }

Status Bar void XScribble: : create. Status. Bar() { m_status. Label = new QLabel("Ready!");

Status Bar void XScribble: : create. Status. Bar() { m_status. Label = new QLabel("Ready!"); m_status. Label->set. Alignment(Qt: : Align. HCenter); m_status. Label->set. Minimum. Size(m_status. Label->size. Hint()); ui. status. Bar->add. Widget( m_status. Label); connect( ui. action. Line, SIGNAL(triggered()), this, SLOT(update. Status. Bar()) ); connect( ui. action. Circle, SIGNAL(triggered()), this, SLOT(update. Status. Bar()) ); update. Status. Bar(); } void XScribble: : update. Status. Bar() { QAction *action = qobject_cast<QAction *>(sender()); if (action) { QString tmp = "scribble tools changed to: " + action->data(). to. String(); m_status. Label->set. Text( tmp); } }

More Widgets on Toolbar • todo

More Widgets on Toolbar • todo

References • C++ GUI Programming with Qt 4

References • C++ GUI Programming with Qt 4