Professional Documents
Culture Documents
2
(http://www.devbean.net/)
2014 6 6
1 ................................................................................................................................. 5
2 Qt .......................................................................................................................... 6
3 Hello, world! ................................................................................................................... 7
4 ........................................................................................................................ 14
5 ............................................................................................................. 18
6 Qt ................................................................................................................ 24
7 MainWindow ........................................................................................................ 28
8 .................................................................................................................... 31
9 .................................................................................................................... 36
10 .................................................................................................................. 40
11 ............................................................................................................... 43
12 .......................................................................................... 47
13 ............................................................................................................... 50
14 ........................................................................................................ 53
15 QMessageBox .......................................................................................... 56
16 Qt5 ............................................................................................ 60
17 ............................................................................................................... 64
18 ......................................................................................................................... 68
19 .................................................................................................... 72
20 event() ....................................................................................................................... 78
21 ............................................................................................................... 81
22 .................................................................................................................. 84
23 ............................................................................................................... 88
24 Qt ....................................................................................................... 90
25 ............................................................................................................... 93
26 ...................................................................................................................... 98
27 ......................................................................................................................... 99
28 .................................................................................................................104
29 .................................................................................................................111
30 Graphics View Framework ...........................................................................................115
31 1 .....................................................................................................118
32 2 .....................................................................................................122
33 3 .....................................................................................................128
34 4 .....................................................................................................132
35 ........................................................................................................................135
36 .......................................................................................................139
37 ..........................................................................................................143
38 .................................................................................................................147
39 .................................................................................................................153
40 ..........................................................................................................160
41 model/view .......................................................................................................162
42 QListWidgetQTreeWidget QTableWidget..............................................................164
43 QStringListModel........................................................................................................170
44 QFileSystemModel......................................................................................................174
45 ........................................................................................................................178
46 ..............................................................................................................183
47 .................................................................................................................187
48 QSortFilterProxyModel................................................................................................193
49 .......................................................................................................196
50 ...................................................................................................201
51 ...................................................................................................203
52 .................................................................................................................215
53 .......................................................................................................221
54 .....................................................................................................................229
55 ..............................................................................................................231
56 ................................................................................................237
57 ............................................................................................239
58 .......................................................................................................242
59 XML ......................................................................................................245
60 DOM XML ..............................................................................................253
61 SAX XML ...................................................................................................258
62 XML ................................................................................................................263
63 QJson JSON ............................................................................................266
64 QJsonDocument JSON .............................................................................270
65 1.........................................................................................................273
66 2.........................................................................................................277
67 3.........................................................................................................284
68 4.........................................................................................................289
69 ........................................................................................................................290
70 ..............................................................................................................293
71 .................................................................................................................297
72 .......................................................................................................299
73 Qt ..........................................................................................................304
74 QObject .......................................................................................................307
75 .................................................................................................................312
76 QML QtQuick 2 ....................................................................................................319
77 QML .................................................................................................................323
78 QML ..........................................................................................................328
79 QML .................................................................................................................333
1
51CTO Qt
C++ GUI Programming with Qt 4, 2nd Editon
2009 8
20 2012 8 20
Qt
Qt 2 2.0
Qt
Qt 5 2012 9
betaQt 5
GUI
Qt 4 Qt 5
Qt 4
Qt 5 Qt 4 Qt 3
Qt 5
Qt 4
Qt 5
Qt
XML Qt
Qt
Qt
2 Qt
Qt C++ GUI Qt
GUI Qt
STL C++ <string> XML
Qt
Qt GUI
Qt Qt
Qt
Qt GPL KDE
GNOME Linux GPL GPL Linux
KDE GPL Qt GPL
Qt GPLv3 LGPL Qt
Qt
3 Hello, world!
Qt Qt Qt
Qt Qt Downloads
QtQt SDKQt LibraryQt Creator
o Qt SDK Qt Qt IDEi18n
Windows 1.7G 780M
Qt
mingw WindowsQt SDK
Qt Qt 4.8.2 Qt SDK
1.2.1 Qt 4.8.1
o Qt Library Qt Qt SDK
Qt IDE
Qt
Qt Qt Creator
IDE mingw gcc
Qt 5 gcc 4.5 Qt SDK
mingw Qt 5 4.4 mingw
4.5
Qt 4 Qt 52012 8
Qt 5 git Qt 5
Windows Qt 5
Windows Qt
5 perl GetOpt::Long python git
Linux Windows Qt 5
Linux Windows
openSUSEopenSUSE Qt 5.0 Development Snapshots Qt 5
Qt 4 Windows
mingw Qt 5 openSUSE gcc 4.6 Qt
5 Windows Windows Qt 5
Qt Creator --Qt
Qt Creator Qt
Qt Qt
Qt HelloWorld Qt Creator
-Applications Qt Gui
mingw
Shadow Build
main.cpp
#include <QApplication>
#include <QLabel>
return app.exec();
}
Qt Creater
#include <QApplication>
#include <QLabel>
return app.exec();
}
C++ exec()
label delete
Qt
Qt Qt
app.exec() app.exec()
main() app
QPaintDevice QApplication
QApplication qApp->quit()QApplication
main() main()
delete
Sailfish OS
#include <QApplication>
QApplication
new delete
label->setAttribute(Qt::WA_DeleteOnClose);
Qt
signal
connect
slot
Qt GoF
// !!! Qt 5
#include <QApplication>
#include <QPushButton>
QPushButton button("Quit");
QObject::connect(&button, &QPushButton::clicked, &QApplication::quit);
button.show();
return app.exec();
}
Qt 5 Qt 4
Qt 5
Qt 4 Qt
Qt Creator main()
Quit
Qt QPushButton
QObject::connect()
Qt 5 QObject::connect()
QMetaObject::Connection
connect()
// !!! Qt 5
connect(sender, signal, receiver, slot);
connect()
sender
const QObject *signal const char *receiver const QObject *
slot const char * signal slot sender
receiver const QObject * signal slot const QMetaMethod &
QMetaMethod QMetaMethod
sender const QObject *signal slot const char
* receiver this receiversender
receiver const QObject * signal slot
PointerToMemberFunction
Functor static
Lambda
QApplication quit2
Qt 5 Lambda
// !!! Qt 5
#include <QApplication>
#include <QPushButton>
#include <QDebug>
QPushButton button("Quit");
QObject::connect(&button, &QPushButton::clicked, [](bool) {
qDebug() << "You clicked me!";
});
button.show();
return app.exec();
}
QMAKE_CXXFLAGS += -std=c++0x
Qt 4 Qt 5 Qt 4 QObject connect()
// !!! Qt 4
#include <QApplication>
#include <QPushButton>
QPushButton button("Quit");
QObject::connect(&button, SIGNAL(clicked()),
&app, SLOT(quit()));
button.show();
return app.exec();
}
Qt
connect()
connect() connect()
Qt
Qt
GUI Qt
//!!! Qt5
#include <QObject>
////////// newspaper.h
class Newspaper : public QObject
{
Q_OBJECT
public:
Newspaper(const QString & name) :
m_name(name)
{
}
void send()
{
emit newPaper(m_name);
}
signals:
void newPaper(const QString &name);
private:
QString m_name;
};
////////// reader.h
#include <QObject>
#include <QDebug>
#include "newspaper.h"
#include "reader.h"
return app.exec();
}
newspaper.hreader.h main.cpp
newspaper.h reader.h main.cpp main()
cpp Qt
make mocmoc
moc Q_OBJECT
Reader QObject
Q_OBJECT Qt 5
static Lambda
public
private
private
Qt
o QObject Lambda
o signals void
o publicprivateprotected
o emit
o QObject::connect()
Qt 4
Qt 4
//!!! Qt4
#include <QObject>
////////// newspaper.h
class Newspaper : public QObject
{
Q_OBJECT
public:
Newspaper(const QString & name) :
m_name(name)
{
}
signals:
void newPaper(const QString &name) const;
private:
QString m_name;
};
////////// reader.h
#include <QObject>
#include <QDebug>
public slots:
void receiveNewspaper(const QString & name) const
{
qDebug() << "Receives Newspaper: " << n ame;
}
};
////////// main.cpp
#include <QCoreApplication>
#include "newspaper.h"
#include "reader.h"
return app.exec();
}
Qt 4 Qt 5
Newspaper
public
privateprotected publicprivate
Qt4
private Qt5
private
6 Qt
Qt 5 Qt 4 Qt 5
Qt 4 Qt 5
Qt 5
Qt
o Qt Core GUI
IOJSON
XML <QtCore>
o Qt Multimedia
<QtMultimedia> pro QT += multimedia
o Qt Network <QtNetwork>
pro QT += network
o Qt Test Qt <QtTest>
pro QT += testlib
Qt
o Qt 3D Qt 3D Qt 3D Qt Quick
3D Qt 3D QML C++ API 3D
o Qt Concurrent
o Qt Graphical Effects
o Qt OpenGL Qt OpenGL Qt 4
Qt 5 Qt 5 OpenGL
QtGui QOpenGL
o Qt Quick 1 Qt 4 QtDeclarative Qt 4
QtQuick
o Qt Script Qt 4
QtQml QJS*
o Qt SVG SVG
Qt 4 Qt 5 Qt 4
o QtCoreQt GUI Qt 5 Qt 4
core JSONXML
o QtMultimedia Qt 5
o QtNetwork Qt 5
o QtOpenVG OpenVG
o QtScriptTools Qt Script
o QtSql SQL
o QtSvg SVG
o QtWebKit Web
o QtXmlXML Qt 5 QtCore
o QtXmlPatterns XQueryXPath
o QtDeclarative
o Phonon
o Qt3SupportQt 3
Qt 4
o QtDesigner Qt Designer
o QtHelp
o QtTest
Windows
o QAxContainer ActiveX
o QAxServer ActiveX
Unix
o QtDBus D-Bus
7 MainWindow
Qt Qt
Qt
QMainWindow Qt
QMainWindow
Qt Creator
MainWindow main()
Qt Creator
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MainWindow win;
win.show();
return app.exec();
}
openSUSE
Window Title
URL
Tool Bar
AreaQt
Area
Word2003 Photoshop
Dock Widget Area Photoshop
Central Widget
Word
Photoshop
Qt
QMainWindow QMainWindow
Qt Creator
QMainWindow Qt 5 Qt
4 Qt Creator Qt 4
Qt 4 widgets pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = qtdemo
TEMPLATE = app
SOURCES += main.cpp \
mainwindow.cpp
HEADERS += mainwindow.h
pro QT
core gui Qt
QT_MAJOR_VERSION 4 Qt 5 widgets
Qt 5 widgets TARGET
TEMPLATE makefile app lib
SOURCES HEADERS
pro
pro
Qt Creator
Qt QAction
Qt QAction
QAction
QAction QAction
Qt Qt
QAction
QAction QAction
QMainWindow QAction
// !!! Qt 5
// ========== mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
private:
void open();
QAction *openAction;
};
#endif // MAINWINDOW_H
// ========== mainwindow.cpp
#include <QAction>
#include <QMenuBar>
#include <QMessageBox>
#include <QStatusBar>
#include <QToolBar>
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setWindowTitle(tr("Main Window"));
statusBar() ;
}
MainWindow::~MainWindow()
{
}
void MainWindow::open()
{
QMessageBox::information(this, tr("Information"), tr("Open"));
}
MainWindow win;
win.show();
return app.exec();
}
MainWindow
MainWindow open()
openAction MainWindow
setWindowTitle() tr() Qt
Qt tr()
tr()
openAction QAction
this this
QIcon Qt
Qt qrc Qt Creator
Qt Qt XML Qt
<RCC>
<qresource prefix="/images">
<file alias="doc-open">document-open.png</file>
</qresource>
</RCC>
Qt pro
RESOURCES QIcon :
:/images/doc-open document-open.png
png Qt jpg
gif Qt
QAction &
File F
setShortcut() QAction Qt
QKeySequence Open
API
tr("Ctrl+O") Qt
PC Mac PC Mac
QKeySequence
setStatusTip() action
open()
Qt 4
// !!! Qt 4
// ========== mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
private slots:
void open();
private:
QAction *openAction;
};
#endif // MAINWINDOW_H
// ========== mainwindow.cpp
#include <QAction>
#include <QMenuBar>
#include <QMessageBox>
#include <QToolBar>
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setWindowTitle(tr("Main Window"));
statusBar();
}
MainWindow::~MainWindow()
{
}
void MainWindow::open()
{
QMessageBox::information(this, tr("Information"), tr("Open"));
}
Qt
Qt Creator
Qt Qt
Qt
Qt Creator
images
document-open.png Qt Creator
:
/images document-open.png
:/images/document-open.png
docuemnt-open.png
docopen.png
:/images/doc-open
fr document-open-fr.png
:/images/fr/doc-open document-open-fr.png
Qt fr QLocale::system().name()
fr_FR:/images/fr/doc-open :/images/doc-open
res.qrc
<RCC>
<qresource prefix="/images">
<file alias="doc-open">document-open.png</file>
</qresource>
<qresource prefix="/images/fr" lang="fr">
<file alias="doc-open">document-open-fr.png</file>
</qresource>
</RCC>
Qt Creator qrc
qrc_res.cpp Qt C++
10
C++
GUI
Qt C++ C++ Qt
Qt mocMeta Object Compiler Qt
C++ Qt moc
C++ Qt moc
C++ C++
Qt
C++ moc
Qt moc C++
o Qt
o tr()
o GUI
o QPointer 0
QObject moc
moc meta-object system
C++ C++ GUI
Qt Qt
GUI
moc
Qt MainWindow
parent parent
QObject QObject QObject
QObject parent
QObject QObject
children()
GUI
QShortcut
QObject::dumpObjectTree() QObject::dumpObjectInfo()
Qt
QObject Qt
Qt
QObject delete parent
parent children() delete Qt
QObject delete
QObject Qt
{
QWidget window;
QPushButton quit("Quit", &window);
}
{
QPushButton quit("Quit");
QWidget window;
quit.setParent(&window);
}
window
quit window
quit quit
quit C++
Qt
Qt parent
11
GUI
Qt
Qt
Qt
Word
Qt
Qt
// !!! Qt 5
QWidget window;
window.setWindowTitle("Enter your age");
window.show();
return app.exec();
}
QSpinBox QSliderQSpinBox
QSlider
connect() connect()
QSpinBox::valueChanged
overloaded QSpinBox QSpinBox
o void valueChanged(int)
&QSpinBox::valueChanged
moc signal
int
signal QSlider
connect() Qt
QHBoxLayout
QSpinBox QSlider
Qt
o QHBoxLayout
o QVBoxLayout
o QFormLayout
HTML form
o QStackedLayout Z
Qt 4
connect()
// !!! Qt 4
QWidget window;
window.setWindowTitle("Enter your age");
window.show();
return app.exec();
}
Qt 5
Qt 5 overloaded signal
1. Qt 4 SIGNAL SLOT
2.
Qt 4 Qt 4
Qt 5
12
Qt
QAction QAction
QMainWindow
QMainWindow QDialog
QDialog QMainWindow
menuBar() toolBar()
menuBar()Qt menuBar()
QMainWindow QWidget QDialog
menuBar()
menuBar()
Qt QMenuBarQMenuBar
addMenu()
Qt &
QAction addAction()
QToolBar QToolBar
addToolBar() menuBar()
addToolBar()
Qt
QAction::setStatusTip()
QMainWindow::menuBar()QMainWindow
statusBar()
statusBar();
statuBar() menuBar()
QStatusBar
13
GUI
Ribbon
Office
Qt QDialog QDialog
QDialog Qt::Dialog parent
parent NULL
parent
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setWindowTitle(tr("Main Window"));
void MainWindow::open()
{
QDialog dialog;
dialog.setWindowTitle(tr("Hello, dialog!"));
dialog.exec();
}
open() QDialog
Hello, dialog! exec()
parent
open()
void MainWindow::open()
{
QDialog dialog(this);
dialog.setWindowTitle(tr("Hello, dialog!"));
dialog.exec();
}
parent QDialog
Qt Qt
Qt QDialog::exec() QDialog::open()
QDialog::show()
exec()
exec() show()
void MainWindow::open()
{
QDialog dialog(this);
dialog.setWindowTitle(tr("Hello, dialog!"));
dialog.show();
}
show()
dialog show()
MainWindow::open()dialog
dialog
void MainWindow::open()
{
QDialog *dialog = new QDialog;
dialog->setWindowTitle(tr("Hello, dialog!"));
dialog->show();
}
QWidget
parent QWidget C++ Qt
parent
dialog
WindowAttribute
void MainWindow::open()
{
QDialog *dialog = new QDialog;
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setWindowTitle(tr("Hello, dialog!"));
dialog->show();
}
setAttribute()QObject
deleteLater()
exec()
14
exec()exec()
Qt
exec()
exec()
void MainWindow::open()
{
QDialog dialog(this);
dialog.setWindowTitle(tr("Hello, dialog!"));
dialog.exec();
qDebug() << dialog.result();
}
exec()qDebug()
std::cout Java System.out.println();
qDebug() exec() dialog
exec() exec()
result()exec()
dialog WA_DeleteOnClose
parent WA_DeleteOnClose
QDialog::exec() QDialog::Accepted
QDialog::Rejected
void MainWindow::open()
{
QDialog dialog(this);
dialog.setWindowTitle(tr("Hello, dialog!"));
dialog.exec();
qDebug() << dialog.result();
}
QDialog
QDialog::show()
show()show()
QDialog::accept() QDialog::reject()
QDialog::done()
QDialog::closeEvent()
//!!! Qt 5
// in dialog:
void UserAgeDialog::accept()
{
emit userAgeChanged(newAge); // newAge is an int
QDialog::accept();
}
// in main window:
void MainWindow::showUserAgeDialog()
{
UserAgeDialog *dialog = new UserAgeDialog(this);
connect(dialog, &UserAgeDialog::userAgeChanged, this,
&MainWindow::setUserAge);
dialog->show();
}
// ...
Qt 4
Qt
sender() signal sender()
sender()
sender()
15 QMessageBox
Qt
Qt
o QColorDialog
o QFileDialog
o QFontDialog
o QInputDialog
o QMessageBox
o QPageSetupDialog
o QPrintDialog
o QPrintPreviewDialog
o QProgressDialog
QMessageBox
Qt
QMessageBox static
o void about(QWidget * parent, const QString & title, const QString & text)
title text parent
OK
QMessageBox
if (QMessageBox::Yes == QMessageBox::question(this,
tr("Question"),
tr("Are you OK?"),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::Yes)) {
QMessageBox::information(this, tr("Hmmm..."), tr("I'm glad to hear that!"));
} else {
QMessageBox::information(this, tr("Hmmm..."), tr("I'm sorry!"));
}
QMessageBox::question() this
MainWindow QWidget QMessageBox QDialog
parent
|
Yes No
Yes Yes
Im glad to hear that!Im sorry!
QMessageBox static
QMessageBox QMessageBox
API
QMessageBox msgBox;
msgBox.setText(tr("The document has been modified."));
msgBox.setInformativeText(tr("Do you want to save your changes?"));
msgBox.setDetailedText(tr("Differences here..."));
msgBox.setStandardButtons(QMessageBox::Save
| QMessageBox::Discard
| QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();
switch (ret) {
case QMessageBox::Save:
qDebug() << "Save document!";
break;
case QMessageBox::Discard:
qDebug() << "Discard changes!";
break;
case QMessageBox::Cancel:
qDebug() << "Close document!";
break;
}
msgBox QMessageBox The
document has been modified.informativeText
detailedText
exec()
KDE Windows 7
16 Qt5
Qt 5
Qt 5
Qt 5
Newspaper
//!!! Qt5
#include <QObject>
////////// newspaper.h
class Newspaper : public QObject
{
Q_OBJECT
public:
Newspaper(const QString & name) :
m_name(name)
{
}
signals:
void newPaper(const QString &name) const;
private:
QString m_name;
};
////////// reader.h
#include <QObject>
#include <QDebug>
////////// main.cpp
#include <QCoreApplication>
#include "newspaper.h"
#include "reader.h"
return app.exec();
}
Newspaper
receiveNewspaper()
Qt 4 Qt 4 Qt
QObject::connect(&newspaper,
(void (Newspaper:: *)(const QString &, const QDate
&))&Newspaper::newPaper,
&reader,
&Reader::receiveNewspaper);
QObject::connect(&newspaper,
static_cast<void (Newspaper:: *)(const QString &, const QDate
&)>(&Newspaper::newPaper),
&reader,
&Reader::receiveNewspaper);
C
(const QString &, const
QDate &)(const QDate &, const QString &)C
C++
Qt
Newspaper Reader
// Newspaper
signals:
void newPaper(const QString &name);
// Reader
void receiveNewspaper(const QString &name, const QDate &date =
QDate::currentDate());
Reader::receiveNewspaper() Newspaper::newPaper()
Reader::receiveNewspaper()
QObject::connect(&newspaper,
static_cast<void (Newspaper:: *)(const QString
&)>(&Newspaper::newPaper),
&reader,
static_cast<void (Reader:: *)(const QString &, const QDate &
=QDate::currentDate())>(&Reader::receiveNewspaper));
C++
Qt 4 Qt 5
Lambda Lambda Qt
5 Qt 5 Lambda
QObject::connect(&newspaper,
static_cast<void (Newspaper:: *)(const QString
&)>(&Newspaper::newPaper),
[=](const QString &name) { /* Your code here. */ });
17
Qt QMessageBox
QDialog
QFileDialog
QFileDialog
QTextEdit
QMainWindow setCentralWidget()
QTextEdit
connect() QAction
/// !!!Qt5
connect(openAction, &QAction::triggered, this, &MainWindow::openFile);
connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);
/// !!!Qt4
connect(openAction, SIGNAL(triggered()), this, SLOT(openFile()));
connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile()));
openFile()
saveFile()
void MainWindow::openFile()
{
QString path = QFileDialog::getOpenFileName(this,
tr("Open File"),
".",
tr("Text Files(*.txt)"));
if(!path.isEmpty()) {
QFile file(path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("Read File"),
tr("Cannot open file:\n%1").arg(path));
return;
}
QTextStream in(&file);
textEdit->setText(in.readAll());
file.close();
} else {
QMessageBox::warning(this, tr("Path"),
tr("You did not select any file."));
}
}
void MainWindow::saveFile()
{
QString path = QFileDialog::getSaveFileName(this,
tr("Open File"),
".",
tr("Text Files(*.txt)"));
if(!path.isEmpty()) {
QFile file(path);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("Write File"),
tr("Cannot open file:\n%1").arg(path));
return;
}
QTextStream out(&file);
out << textEdit->toPlainText();
file.close();
} else {
QMessageBox::warning(this, tr("Path"),
tr("You did not select any file."));
}
}
openFile() QFileDialog::getOpenFileName()
o parentQt
o caption
o dir. /
Windows Linux
C:\\
o filter
Image Files(*.jpg
*.png) jpg png ;;
JPEG Files(*.jpg);;PNG Files(*.png)
o selectedFilter
o options enum
QFileDialog::Option |
QFileDialog::getOpenFileName() path
path
saveFile() QFileDialog::getSaveFileName()
WindowsMac OS Linux
QFileDialog
QFileDialog QMessageBox
QFile
QFile::open()
txt
QFile::open() true
QTextStream::readAll()
QTextEdit saveFile()
<< QTextEdit
QTextStream::readAll() 100M
o ch17-qt4.zip
o ch17-qt5.zip
18
event Qt
event drive
C
Qt Qt
Qt
QPushButton
clicked() GUI Swing
JButton ActionListener GUI Qt
Qt
connect()Qt
Qt
EventLabel
QLabel
clicked() EventLabel
Qt main() QCoreApplication
exec() Qt exec()
Qt
Qt
QEvent Qt QObject
event()event()
event handler
QWidget keyPressEvent()
keyReleaseEvent() mouseDoubleClickEvent() mouseMoveEvent()
mousePressEvent() mouseReleaseEvent() protected virtual
return a.exec();
}
mouseReleaseEvent() QString
C sprintf() QString
label
mouseMoveEvent()
QWidget mouseTracking
mouseMoveEvent() mouseTracking false
mouseMoveEvent()
mouseTracking true mouseMoveEvent()
main()
19
1. 2012-09-29
//!!! Qt5
// ---------- custombutton.h ---------- //
class CustomButton : public QPushButton
{
Q_OBJECT
public:
CustomButton(QWidget *parent = 0);
private:
void onButtonCliecked();
};
void CustomButton::onButtonCliecked()
{
qDebug() << "You clicked this!";
}
return a.exec();
}
// CustomButton
...
protected:
void mousePressEvent(QMouseEvent *event);
...
CustomButton mousePressEvent()
left
You clicked this!left
QPushButton
mousePressEvent() clicked()
CustomButton
clicked()
Qt
Qt accept() ignore()
Qt Qt
isAccepted()
accept() ignore()
Qt
accept() ignore()
Qt protected
Qt
accept() ignore()
Qt accept QWidget
ignore() QWidget
QWidget
QWidget
mousePressEvent()
//!!! Qt5
void QWidget::mousePressEvent(QMouseEvent *event)
{
event->ignore();
if ((windowType() == Qt::Popup)) {
event->accept();
QWidget* w;
while ((w = QApplication::activePopupWidget()) && w != this){
w->close();
if (QApplication::activePopupWidget() == w)
w->hide(); // hide at least
}
if (!rect().contains(event->pos())){
close();
}
}
}
accept() ignore()
MainWindow CustomWidget
CustomButton CustomButtonEx mousePressEvent()
CustomButtonEx
CustomButtonEx
accept()
ignore() CustomButtonEx mousePressEvent()
event->accept()QEvent accept
CustomButtonEx event->accept()
event->ignore()
CustomButtonEx
CustomWidget
CustomWidget mousePressEvent()
QWidget::mousePressEvent(event)
CustomButtonEx
CustomWidget
MainWindow
QWidget::mousePressEvent(event) event->ignore()
QWidget event->ignore()
accept() ignore()
accept() ignore()
QCloseEvent accept() Qt ignore()
//!!! Qt5
...
textEdit = new QTextEdit(this);
setCentralWidget(textEdit);
connect(textEdit, &QTextEdit::textChanged, [=]() {
this->setWindowModified(true);
});
setWindowTitle("TextPad [*]");
...
setWindowTitle() [*]
setWindowModified(true)Qt [*] *
Lambda QTextEdit::textChanged() windowModified
true closeEvent()
Yes
20 event()
event()Qt
QObject event()event()
event handler
event()
event() QWidget tab
QWidget event()
QEvent::type()
QEvent::Type true
event()
QObject::event()event()
//!!! Qt5
bool QObject::event(QEvent *e)
{
switch (e->type()) {
case QEvent::Timer:
timerEvent((QTimerEvent*)e);
break;
case QEvent::ChildAdded:
case QEvent::ChildPolished:
case QEvent::ChildRemoved:
childEvent((QChildEvent*)e);
break;
// ...
default:
if (e->type() >= QEvent::User) {
customEvent(e);
break;
}
return false;
}
return true;
}
Qt 5 QObject::event()Qt 4
Qt QEvent::type()
event->type() QEvent::Timer timerEvent()
QWidget::event()
switch (event->type()) {
case QEvent::MouseMove:
mouseMoveEvent((QMouseEvent*)event);
break;
// ...
}
timerEvent() mouseMoveEvent()
event handlerevent()
event()
protected virtual Qt
event()
event() QEvent::type()
event()
event()
CustomTextEdit tab
21
Qt QEvent QObject
event() event() event()
protected event()
event() Qt
QObject eventFilter()
bool
event true false
watched
watched
MainWindow::MainWindow()
{
textEdit = new QTextEdit;
setCentralWidget(textEdit);
textEdit->installEventFilter(this);
}
MainWindow eventFilter()
textEdit
true
false
eventFilter()
QObject::installEventFilter()
QObject *eventFilter()
QObject QObject
eventFilter()
QObject::removeEventFilter()
installEventFilter()
event() Tab
delete true
Qt
22
Qt Qt
Qt
Qt
1.
win32 API WndProc()
switch message
switch(message)
{
case WM_PAINT:
// ...
break;
case WM_DESTROY:
// ...
break;
...
}
2. Qt
o mouseEvent()
o keyPressEvent()
o
Qt Qt
event() QMouseEvent
event() mouseEvent()
event()
2. event()
event() QMouseEvent
event()Qt
QObject
QApplication QCoreApplication
installEventFilter()
eventFilter()
QApplication
eventFilter()
event()
protected QObject
Qt
QCoreApplication::notify()
QCoreApplication::notify()
Qt
1. paintEvent()mousePressEvent()
2. event()event()QObject QWidget
3.
4. QCoreApplication::instance()
notify()
disabled
5. QCoreApplication::notify()
QCoreApplication
protected:
void mousePressEvent(QMouseEvent *)
{
qDebug() << "mousePressEvent";
}
private:
QObject *m_watched;
};
QApplication::eventFilter
eventFilter
event
mousePressEvent
event()
23
Qt
Qt Qt
QEvent
QEvent QEvent::Type
type event()
QEvent::type()
Qt registerEventType()
QEvent Qt
2. event receiver
notify()
post
Qt::NormalEventPriority
Qt
QObject::customEvent() QEvent
event
event()
24 Qt
Qt API
QPainterQPainterDevice QPaintEngine
QPainter QPaintDevice
QPainter QPainter QPaintEngine
QPainterQPaintEngine QPainter
QPaintDevice
QPaintEngine QPainter QPaintDevice
QPaintEngine
Qt API
Qt QPainter
QPainterDevice QPaintEngine
QPainter
QPainter
//!!! Qt4/Qt5
QWidget paintEvent() Qt
PaintedWidget
//!!! Qt4/Qt5
PaintedWidget::PaintedWidget(QWidget *parent) :
QWidget(parent)
{
resize(800, 600);
setWindowTitle(tr("Paint Demo"));
}
void PaintedWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.drawLine(80, 100, 650, 500);
painter.setPen(Qt::red);
painter.drawRect(10, 10, 100, 400);
painter.setPen(QPen(Qt::green, 5));
painter.setBrush(Qt::blue);
painter.drawEllipse(50, 150, 400, 200);
}
paintEvent()
QPainter paintEvent()
QPainter
QPainter
QPainter
QPen QBrush
OpenGLOpenGL
OpenGL
QPainter
5
OpenGLQPainter Java2D
QPainter paintEvent()
QPainter
25
Qt
QBrush QPen
QBrush QPainter
style() Qt::BrushStyle Qt::NoBrush
color() Qt
Qt::GlobalColor QColor
gradient() Qt::LinearGradientPattern
Qt::RadialGradientPattern Qt::ConicalGradientPattern
QGradient Qt QLinearGradientQConicalGradient
QRadialGradient QGradient
QBrush brush(gradient);
Qt::TexturePattern texture()
Qt::TexturePattern setTexture()QBrush style()
Qt::TexturePattern
QPen QPainter
style() brush()
capStyle() QPainter
joinStyle() width() widthF()
0 width 0QPainter
1 1
set
QPainter painter(this);
QPen pen(Qt::green, 3, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin);
painter.setPen(pen);
QPainter painter(this);
QPen pen; // creates a default pen
pen.setStyle(Qt::DashDotLine);
pen.setWidth(3);
pen.setBrush(Qt::green);
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin);
painter.setPen(pen);
set
0 Qt::SquareCap
Qt::BevelJoin
setDashPattern()
QPen pen;
QVector<qreal> dashes;
qreal space = 4;
dashes << 1 << space << 3 << space << 9 << space
<< 27 << space << 9 << space;
pen.setDashPattern(dashes);
Qt::SquareCap
Qt::FlatCap Qt::RoundCap
C++ GUI Programming with Qt 4, 2nd Edition
QPainter
26
API Qt
void paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setPen(QPen(Qt::black, 5, Qt::DashDotLine, Qt::RoundCap));
painter.setBrush(Qt::yellow);
painter.drawEllipse(50, 150, 200, 150);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(Qt::black, 5, Qt::DashDotLine, Qt::RoundCap));
painter.setBrush(Qt::yellow);
painter.drawEllipse(300, 150, 200, 150);
}
painter.setRenderHint(QPainter::Antialiasing, true);
Antialiasing true
QPainter QPainter
Java2DOpenGL
Photoshop 1 3200%
Photoshop
1
1 Photoshop
27
Qt
QBrush
Qt QLinearGradientQRadialGradient
QConicalGradient Qt API
void paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
QLinearGradient linearGradient(60, 50, 200, 200);
linearGradient.setColorAt(0.2, Qt::white);
linearGradient.setColorAt(0.6, Qt::green);
linearGradient.setColorAt(1.0, Qt::black);
painter.setBrush(QBrush(linearGradient));
painter.drawEllipse(50, 50, 200, 150);
}
paintEvent()
QLinearGradient QLinearGradient
x1y1x2y2
(60, 50) (200, 200)
setColorAt()
color wheel
void ColorWheel::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
conicalGradient.setColorAt(0.0, Qt::red);
conicalGradient.setColorAt(60.0/360.0, Qt::yellow);
conicalGradient.setColorAt(120.0/360.0, Qt::green);
conicalGradient.setColorAt(180.0/360.0, Qt::cyan);
conicalGradient.setColorAt(240.0/360.0, Qt::blue);
conicalGradient.setColorAt(300.0/360.0, Qt::magenta);
conicalGradient.setColorAt(1.0, Qt::red);
painter.translate(r, r);
QBrush brush(conicalGradient);
painter.setPen(Qt::NoPen);
painter.setBrush(brush);
painter.drawEllipse(QPoint(0, 0), r, r);
}
QPainter 150
cx cy
(0, 0) 0
setColorAt()
conicalGradient.setColorAt(0.0, Qt::red);
conicalGradient.setColorAt(60.0/360.0, Qt::yellow);
60 360 60.0/360.0
1.0
painter.translate(r, r);
QPainter::translate(x, y)
(x, y) translate(r, r) (r, r)
(-r, -r)
drawEllipse() (r, r)
(0, 0) (r, r)
PS translate() translate()
void ColorWheel::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
conicalGradient.setColorAt(0.0, Qt::red);
conicalGradient.setColorAt(60.0/360.0, Qt::yellow);
conicalGradient.setColorAt(120.0/360.0, Qt::green);
conicalGradient.setColorAt(180.0/360.0, Qt::cyan);
conicalGradient.setColorAt(240.0/360.0, Qt::blue);
conicalGradient.setColorAt(300.0/360.0, Qt::magenta);
conicalGradient.setColorAt(1.0, Qt::red);
QBrush brush(conicalGradient);
painter.setPen(Qt::NoPen);
painter.setBrush(brush);
painter.drawEllipse(QPoint(r, r), r, r);
}
QConicalGradient
28
translate()
Qt
QPainter
QPaintDeviceQPaintEngine QPainter
Qt QPainter QPaintDevice
QPainter
QWidgetQPixmapQPictureQImage QPrinter QPaintEngine QPainter
QPaintDeice QPaintDevice
(0, 0)x y
1/72
Qt 11
1 (x, y) (x +
0.5, y + 0.5)
Qt
Qt
(1, 2)
Qt
QRect::right() QRect::bottom()
QRect::right() left() + width() 1QRect::bottom() top() + height() 1
QRectFQRectF
QRectF::right() QRectF::bottom()
QRect x() + width() y() + height() right() bottom()
Qt
;-P
QPainter::save() QPainter::restore()
QPainter
QPainter save()
restore()save()restore()
QPainter save()restore()
void PaintDemo::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.fillRect(10, 10, 50, 100, Qt::red);
painter.save();
painter.translate(100, 0); // 100px
painter.fillRect(10, 10, 50, 100, Qt::yellow);
painter.restore();
painter.save();
painter.translate(300, 0); // 300px
painter.rotate(30); // 30
painter.fillRect(10, 10, 50, 100, Qt::green);
painter.restore();
painter.save();
painter.translate(400, 0); // 400px
painter.scale(2, 3); // 2 3
painter.fillRect(10, 10, 50, 100, Qt::blue);
painter.restore();
painter.save();
painter.translate(600, 0); // 600px
painter.shear(0, 1); // 1
painter.fillRect(10, 10, 50, 100, Qt::cyan);
painter.restore();
}
translate()
Qt QPainter
QPaintDevice
Qt viewport-window
400400
void PaintDemo::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setWindow(0, 0, 200, 200);
painter.fillRect(0, 0, 200, 200, Qt::red);
}
(0, 0) 200px
(400, 400) (200, 200)
translate()translate()
setWindow()
400400
painter.translate(200, 200);
painter.setWindow(-160, -320, 320, 640);
void PaintDemo::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setViewport(0, 0, 200, 200);
painter.fillRect(0, 0, 200, 200, Qt::red);
}
setWindow() setViewport()window
viewport
(0, 0) 200px
1/4 1/16
(0, 0)
400px (0, 0) 200px
200px 400px
200px 400px (200, 200) ((0 + 200 * 200 /
400), (0 + 200 * 200 / 400)) = (100, 100)
QPainter
window-viewport
29
QPainterDevice
QPaintDevice
QPainter QPaintDevice Qt
Qt4
Qt5
QPixmap
QPixmap QPixmap
8 3 3
1 1 1 0 1
QBitmap
QBitmap
QPixmap QBitmap
void paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPixmap pixmap("qt-logo.png");
QBitmap bitmap("qt-logo.png");
painter.drawPixmap(10, 10, 250, 125, pixmap);
painter.drawPixmap(270, 10, 250, 125, bitmap);
QPixmap whitePixmap("qt-logo-white.png");
QBitmap whiteBitmap("qt-logo-white.png");
painter.drawPixmap(10, 140, 250, 125, whitePixmap);
painter.drawPixmap(270, 140, 250, 125, whiteBitmap);
}
QPixmap QImage
QImage QPixmap
3 x 3 QImage setPixel()
QImage RGB
QImage QImage::Format_Indexed8
QPicture svgpdfps
QPaintDevice QPainter
QPicture QPainter
QPainter QPainter::begin()
QPicture QPainter::end()
QPicture picture;
QPainter painter;
painter.begin(&picture); // picture
painter.drawEllipse(10, 20, 80, 70); //
painter.end(); //
picture.save("drawing.pic"); // picture
QPicture::load()
QPicture picture;
picture.load("drawing.pic"); // picture
QPainter painter;
painter.begin(&myImage); // myImage
painter.drawPicture(0, 0, picture); // (0, 0) picture
painter.end(); //
QPicture::play() QPainter
Graphics View 2D
Graphics View
Graphics View BSP Binary Space
Partitioning tree
QPainter QPainter
drawLine() drawPolygon()
Graphics Viewscene
add()
QPainter
Graphics View
QGraphicsScene scene;
scene.addLine(0, 0, 150, 150);
QGraphicsView view(&scene);
view.setWindowTitle("Graphics View");
view.resize(500, 500);
view.show();
return app.exec();
}
QGraphicsScene
addLine() (0, 0) (150, 150)
150px
GraphicsView
scene QGraphicsScene QWidget
QGraphicsView(QWidget *parent)
scene sceneRect()
QGraphicsScene scene;
scene.setSceneRect(0, 0, 300, 300);
scene.addLine(0, 0, 150, 150);
QGraphicsView view(&scene);
view.setWindowTitle("Graphics View");
// view.resize(500, 500);
view.show();
view.resize()QGraphicsScene sceneRect
QGraphicsView QGraphicsScene
view.resize()
31 1
Qt
http://qtcollege.co.il/developing-a-qt-snake-game/
o QGraphicsScene GUI
o QGraphicsItem
o QGraphicsView
QGraphicsScene
QGraphicsView
GUI
QGraphicsView
QGraphicsView
QtDesigner
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class QGraphicsScene;
class QGraphicsView;
class GameController;
private slots:
void adjustViewSize();
private:
void initScene();
void initSceneBackground();
QGraphicsScene *scene;
QGraphicsView *view;
GameController *game;
};
#endif // MAINWINDOW_H
MainWindow
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
scene(new QGraphicsScene(this)),
view(new QGraphicsView(scene, this)),
game(new GameController(*scene, this))
{
setCentralWidget(view);
resize(600, 600);
initScene();
initSceneBackground();
singleShot()
msec receiver
member 0 0ms
this->adjustViewSize() this->adjustViewSize();
It is very convenient to use this function because you
do not need to bother with a timerEvent or create a local QTimer object
timerEvent() QTimer
QTimer::signleShot(0, ...) QTimer
QTimer
QTimer::signleShot(0, ...)
paintEvent() adjustViewSize()
QTimer adjustViewSize() flash
flash callLater() initScene() initSceneBackground()
void MainWindow::initScene()
{
scene->setSceneRect(-100, -100, 200, 200);
}
void MainWindow::initSceneBackground()
{
QPixmap bg(TILE_SIZE, TILE_SIZE);
QPainter p(&bg);
p.setBrush(QBrush(Qt::gray));
p.drawRect(0, 0, TILE_SIZE, TILE_SIZE);
view->setBackgroundBrush(QBrush(bg));
}
initSceneBackground() TILE_SIZE
QPixmap
QPixmap
32 2
QGraphicsScene
QGraphicsItem
QGraphicsItem
Food
QGraphicsItemQGraphicsItem
boundingRect() paint()
boundingRect()
paint() QPainter
food.h food.cpp
#include <QGraphicsItem>
#endif // FOOD_H
#include "constants.h"
#include "food.h"
Food::Food(qreal x, qreal y)
{
setPos(x, y);
setData(GD_Type, GO_Food);
}
painter->setRenderHint(QPainter::Antialiasing);
painter->fillPath(shape(), Qt::red);
painter->restore();
}
GameController
GameController
30
30 30
for
scene->addItem(snake);
scene->installEventFilter(this);
resume();
}
GameController 1000 / 33
301000 / 33 = 30GameController scene snake
GameController
void GameController::pause()
{
disconnect(&timer, SIGNAL(timeout()),
scene, SLOT(advance()));
}
void GameController::resume()
{
connect(&timer, SIGNAL(timeout()),
scene, SLOT(advance()));
}
pause() resume()
GameController MainWindow
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
game(new GameController(scene, this))
{
...
}
GameController
start
1.
boundingRect()
2.
growing growing growing
3. advance() 30
GameController
boundingRect()
QRectF Snake::boundingRect() const
{
qreal minX = head.x();
qreal minY = head.y();
qreal maxX = head.x();
qreal maxY = head.y();
x y
x y
shape()
return path;
}
shape()paint()
33 3
void Snake::moveLeft()
{
head.rx() -= SNAKE_SIZE;
if (head.rx() < -100) {
head.rx() = 100;
}
}
void Snake::moveRight()
{
head.rx() += SNAKE_SIZE;
if (head.rx() > 100) {
head.rx() = -100;
}
}
void Snake::moveUp()
{
head.ry() -= SNAKE_SIZE;
if (head.ry() < -100) {
head.ry() = 100;
}
}
void Snake::moveDown()
{
head.ry() += SNAKE_SIZE;
if (head.ry() > 100) {
head.ry() = -100;
}
}
move SNAKE_SIZE
void Snake::handleCollisions()
{
QList collisions = collidingItems();
handleCollisions()
collidingItems()
o Qt::ContainsItemShape shape()
o Qt::IntersectsItemShapeshape()
o Qt::ContainsItemBoundingRectboundingRect()
o Qt::IntersectsItemBoundingRectboundingRect()
Qt::IntersectsItemShapeFood
boundingRect()
Qt::IntersectsItemShape boundingRect()
Food
setData(GD_Type, GO_Food);
QGraphicsItem::setData()
Qt
Food GD_Type
GO_Food GD_Type GO_Food
QGraphicsItem Food
advance()
if (growing > 0) {
QPointF tailPoint = head;
tail << tailPoint;
growing -= 1;
} else {
tail.takeFirst();
tail << head;
}
switch (moveDirection) {
case MoveLeft:
moveLeft();
break;
case MoveRight:
moveRight();
break;
case MoveUp:
moveUp();
break;
case MoveDown:
moveDown();
break;
}
setPos(head);
handleCollisions();
}
tickCounter speed
speed
speed tickCounter % speed != 0
moveDirection NoMove
growing 0
0 growing
growing 7 advance() 7 >
1 growing 1 growing 0
34 4
GameController
GameController
QGraphicsScene
QGprahicsScene
keyPressEvent()
QGraphicSceneis-a
QGraphcisScene
GameController
QGraphicsScene
GameController
handleKeyPressed()
addNewFood();
}
delete
addNewFood() new
void GameController::addNewFood()
{
int x, y;
do {
x = (int) (qrand() % 100) / 10;
y = (int) (qrand() % 100) / 10;
x *= 10;
y *= 10;
} while (snake->shape().contains(snake->mapFromScene(QPointF(x + 5, y +
5))));
addNewFood()
shape()
shape() xy
QGraphicsItem::mapFromScene()
void GameController::gameOver()
{
scene.clear();
gameOver()
gameOver()
QTimer QTimer::singleShot(0, ...)
update QTimer update
Wall
github
clone
snake
gitgit@github.com:devbean/snake-game.git
35
Qt
Qt I/O
Qt QIODevice I/O
I/O
Qt4
Qt5
Qt4 Qt5 I/O Qt5
QFileDevice
o QIODevice I/O
o QFlie
o QTemporaryFile
o QBuffer QByteArray
o QProcess
o QAbstractSocket
o QTcpSocketTCP
o QUdpSocket UDP
o QSslSocket SSL/TLS
o QFileDeviceQt5
QFile
I/O I/O
QFile
Qt5 QFileDevice
Qt4 QFile Qt5
QFile
setFileName()QFile /
C:/windows Windows
QFile
QDataStream QTextStream QIODevice
read()readLine()readAll() write()
QFileInfo
QFile
QFile file("in.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Open file failed.";
return -1;
} else {
while (!file.atEnd()) {
qDebug() << file.readLine();
}
}
QFileInfo info(file);
qDebug() << info.isDir();
qDebug() << info.isExecutable();
qDebug() << info.baseName();
qDebug() << info.completeBaseName();
qDebug() << info.suffix();
qDebug() << info.completeSuffix();
return app.exec();
}
QFile in.txt
app.applicationFilePath();
app.applicationDirPath();
QDir::currentPath()
open()
fopen() r open()
bool
while
QFileInfo QFileInfo
isDir() isExecutable()
baseName()suffix()
baseName() completeBaseName() suffix()
completeSuffix()
QFileInfo fi("/tmp/archive.tar.gz");
QString base = fi.baseName(); // base = "archive"
QString cbase = fi.completeBaseName(); // base = "archive.tar"
QString ext = fi.suffix(); // ext = "gz"
QString ext = fi.completeSuffix(); // ext = "tar.gz"
36
QDataStream QIODevice
CPU
Windows PC
Solaris SPARC
QIODeviceQDataStream
QFile file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
out << QString("the answer is");
out << (qint32)42;
file.dat
file
QDataStream out std::cout QDataStream
<<the answer is 42
;-P
out file
file
Qt qint32
Qt char *
\0 32 \0
32
file.dat
file
file.close(); // file.flush();
QFile file("file.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
QString str;
qint32 a;
in >> str >> a;
Qt Qt
QFile file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
//
out << (quint32)0xA0B0C0D0;
out << (qint32)123;
out.setVersion(QDataStream::Qt_4_0);
//
out << lots_of_interesting_data;
dat
0xA0B0C0D0
0xA0B0C0D0
Java class
0xCAFEBABE 32
quint32 32
123
out.setVersion(QDataStream::Qt_4_0);
Qt
Qt Qt 4.0
QFile file("file.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
//
quint32 magic;
in >> magic;
if (magic != 0xA0B0C0D0) {
return BAD_FILE_FORMAT;
}
//
qint32 version;
in >> version;
if (version < 100) {
return BAD_FILE_TOO_OLD;
}
if (version > 123) {
return BAD_FILE_TOO_NEW;
}
QFile file("file.dat");
file.open(QIODevice::ReadWrite);
QDataStream stream(&file);
QString str = "the answer is 42";
QString strout;
strout file.flush();
<<
0
37
QTextStream
QTextStream QDataStream XML
HTML QTextStream Qt XML
QTextStream Unicode
QTextStream 16
QChar C++ int
QFile data("file.txt");
if (data.open(QFile::WriteOnly | QIODevice::Truncate)) {
QTextStream out(&data);
out << "The answer is " << 42;
}
open() QIODevice::Truncate
QIODevice::NotOpen
QIODevice::ReadOnly
QIODevice::WriteOnly
QIODevice::ReadWrite
QIODevice::Append
QIODevice::Truncate
\n
QIODevice::Text Win32 \r\n
QIODevice::Unbuffered
QFile::WriteOnly | QIODevice::Truncate
QIODevice::Truncate
QTextStream QDataStream
QFile data("file.txt");
if (data.open(QFile::ReadOnly)) {
QTextStream in(&data);
QString str;
int ans = 0;
in >> str >> ans;
}
QDataStream QTextStream
str The answer is 42ans 0
QDataStream
QTextStream::readLine() QTextStream::readAll()
QString
QTextStream Unicode
stream.setCodec("UTF-8");
bin setIntegerBase(2)
oct setIntegerBase(8)
dec setIntegerBase(10)
hex setIntegerBase(16)
fixed setRealNumberNotation(FixedNotation)
scientific setRealNumberNotation(ScientificNotation)
left setFieldAlignment(AlignLeft)
right setFieldAlignment(AlignRight)
center setFieldAlignment(AlignCenter)
flush flush()
reset reset()
ws skipWhiteSpace()
bom setGenerateByteOrderMark(true)
12345678
out.setIntegerBase(2);
out << 12345678;
1234567890
0xBC614E
QIODeviceQTextStream QString
QString str;
QTextStream(&str) << oct << 31 << " " << dec << 25 << endl;
38
containerscollections
C++
Standard Template Library STL
Qt STL
STL Qt API
Qt STL
Qt
copy on write
Qt Java STL
Java
STL Qt STL
STL Qt
Qt foreach C++ 11
foreach
Qt QListQLinkedListQVectorQStack QQueue
QList
QLinkedList
QVectorQStack QQueue LIFO FIFO
Qt QMapQMultiMapQHashQMultiHash QSetMulti
Hash
Hash
Qt
o QList<T> T
QList
QList::append() QList::prepend()
QList::insert()QList
QStringList QList<QString>
o QLinkedList<T> QList
QList
QLinkedList
QList
o QVector<T>
o QStack<T> QVector LIFO QVector
push()pop() top()
o QSet<T>
int
doubleQt QStringQDate QTime
QObject QWidgetQTimer
QList<QWidget> QWidget
QList<QWidget *>
QMap QHashQMap
operator<()QHash operator==() qHash()
struct Movie
{
int id;
QString title;
QDate releaseDate;
};
struct
QList<Movie> movs;
Qt QDataStream
QDataStream operator<<() operator>>()
QLinkedList QLinkedList
QVector QVector
O
O O
o O(1)
QLinkedList::insert()
o O(log n)
qBinaryFind()
o O(n)
QVector::insert()
o O(n log n)
o O(n)
Qt
O(1)
O(n) n O(1)
15000
18 4812
1620521162445001012203640846132818010228122761432416372
out 16372 Unicode 15000
o QString 4 20
o 20 4084 2 12
2
memcry() C++ Qt
QVector<T>
QVector<T>
QHash<Key, T>QHash 2
qHash(key) %
QHash::capacity()QHash::capacity() QSet<T>
QCache<Key, T>
Qt QVector<T>
QHash<Key, T>QSet<T>QString QByteArray
o reserve(size)
o squeeze()
reserve()
squeeze()
39
Qt Java STL
const
Java
Java Qt4 Qt
STL API
Java
Java
QMap<Key,
T>, QMultiMap<Key, T> QMapIterator<T> QMutableMapIterator<T>
QHash<Key,
T>, QMultiHash<Key, T> QHashIterator<T> QMutableHashIterator<T>
QList<QString> list;
list << "A" << "B" << "C" << "D";
QListIterator<QString> i(list);
while (i.hasNext()) {
qDebug() << i.next();
}
list
A hasNext()
next()next()
hasPrevious() previous()
API
QListIterator
QMutableListIterator
QMutableListIterator<int> i(list);
while (i.hasNext()) {
if (i.next() % 2 != 0) {
i.remove();
}
}
QMutableListIterator
next()remove()
remove()
setValue()
QMutableListIterator<int> i(list);
while (i.hasNext()) {
if (i.next() > 128) {
i.setValue(128);
}
}
remove()setValue()next()
const setValue()
QMutableListIterator<int> i(list);
while (i.hasNext()) {
i.next() *= 2;
}
STL
QList<T>, QQueue<T> QList<T>::const_iterator QList<T>::iterator
QMap<Key,
T>, QMultiMap<Key, T> QMap<Key, T>::const_iterator QMap<Key, T>::iterator
QHash<Key,
T>, QMultiHash<Key, T> QHash<Key, T>::const_iterator QHash<Key, T>::iterator
STL ++
* QVector QStack
typedef T *const_iterator typedef
const T *
QList<QString> list;
list << "A" << "B" << "C" << "D";
QList<QString>::iterator i;
for (i = list.begin(); i != list.end(); ++i) {
*i = (*i).toLower();
}
STL
const_iterator
QList<QString>::const_iterator i;
for (i = list.constBegin(); i != list.constEnd(); ++i) {
qDebug() << *i;
}
QMap<int, int>::const_iterator i;
for (i = map.constBegin(); i != map.constEnd(); ++i) {
qDebug() << i.key() << ":" << i.value();
}
//
const QList<QString> sizes = splitter->sizes();
QList<QString>::const_iterator i;
for (i = sizes.begin(); i != sizes.end(); ++i)
...
//
QList<QString>::const_iterator i;
for (i = splitter->sizes().begin();
i != splitter->sizes().end(); ++i)
...
const const STL
const
Java
foreach
Qt foreach
Qt C++ 11 foreach
QLinkedList<QString> list;
...
QString str;
foreach (str, list) {
qDebug() << str;
}
QLinkedList<QString> list;
...
QLinkedListIterator<QString> i(list);
while (i.hasNext()) {
qDebug() << i.next();
}
QPair<int, int>
foreach foreach
QLinkedList<QString> list;
...
foreach (const QString &str, list) {
qDebug() << str;
}
Qt foreach
foreach const
40
Qt C++
1
0
CPU
1
Qt4
Qt
Qt4
QSharedData QSharedDataPointer
QPen QPen
void QPen::detach()
{
if (d->ref != 1) {
... //
}
}
Qt
QPainter paint;
paint.begin(&p2); // p2 p1
paint.drawText(0,50, "Hi");
paint.end();
p1 p2 QPainter::begin()
p2
const STL
QList QVector at()
[] []
Qt at()
begin()end() const
Qt
const_iteratorconstBegin() constEnd()
41 model/view
Qt
Smalltalk MVC
MVC Model-View-Controller --
MVC
API
MVC
Qt 4 model/view
MVC V C model/view
delegate
Model View
model/view MV
QAbstractItemModel
QAbstractItemModel
QAbstractListModel
QAbstractTableModel
Qt
o QStringListModel
o QStandardItemModel
o QFileSystemModel
o QSqlQueryModelQSqlTableModel QSqlRelationalTableModel
QAbstractItemModel
QAbstractListModel QAbstractTableModel
Qt QListView QTableView
QTreeView QAbstractItemView
QAbstractItemView
QAbstractItemDelegate Qt 4.4
QStyledItemDelegateQStyledItemDelegate QItemDelegate
QStyledItemDelegate
QStyledItemDelegate Qt style sheets
model/view Qt
QListWidgetQTreeWidget
QTableWidget
42 QListWidgetQTreeWidget QTableWidget
model/view QListWidget
QTreeWidget QTableWidget model/view
model/view
QListWidgetQTreeWidget QTableWidget
view model/view
QListWidget
QListWidget
setLayout(layout);
connect(listWidget, SIGNAL(currentTextChanged(QString)),
label, SLOT(setText(QString)));
QListWidget QListWidget
QListWidget QListWidgetItem QListWidgetItem
listWidget listWidget
QListWidget
addItem() insertItem()
QListWidgetItem type
QListWidgetItem::Type QListWidgetItem::UserType
QListWidgetItem QListWidget
QListWidget
listWidget->setViewMode(QListView::IconMode);
QTreeWidget
QTreeWidget
QListWidget
QTreeWidgetItem
QTreeView
QTreeWidget
QTreeWidget treeWidget;
treeWidget.setColumnCount(1);
treeWidget.show();
QTreeWidget setColumnCount()
QTreeWidget
QTreeWidgetItemQTreeWidgetItem
3
QListWidgetItem
QListWidgetItem type
QStringList QString
QTreeWidgetItemroot
root
QTreeWidgetItem QTreeWidget
QTreeWidget QList
QTreeWidget treeWidget;
QStringList headers;
headers << "Name" << "Number";
treeWidget.setHeaderLabels(headers);
QStringList rootTextList;
rootTextList << "Root" << "0";
QTreeWidgetItem *root = new QTreeWidgetItem(&treeWidget, rootTextList);
new QTreeWidgetItem(root, QStringList() << QString("Leaf 1") << "1");
QTreeWidgetItem *leaf2 = new QTreeWidgetItem(root,
QStringList() << QString("Leaf 2") << "2");
leaf2->setCheckState(0, Qt::Checked);
treeWidget.show();
setHeaderHidden()
QTableWidget
QTableWidgetQTableWidget
QTableWidget tableWidget;
tableWidget.setColumnCount(3);
tableWidget.setRowCount(5);
QStringList headers;
headers << "ID" << "Name" << "Age" << "Sex";
tableWidget.setHorizontalHeaderLabels(headers);
tableWidget.show();
QTableWidget QStringList
setItem()
0
QTableWidgetItem Qt row col
QTableWidgetItem QListWidgetItem QTreeWidgetItem
43 QStringListModel
listtable tree
model/view
model/view
model/viewmodel view Qt
QStringListModel
Qt
QStringListModel
QStringListModel
QStringList QStringList
QList<QString>
QStringListModel QListView QComboBox
QStringListModel
MyListView::MyListView()
{
QStringList data;
data << "Letter A" << "Letter B" << "Letter C";
model = new QStringListModel(this);
model->setStringList(data);
QStringList
QStringListModel
QStringListModel QStringList
void MyListView::insertData()
{
bool isOK;
QString text = QInputDialog::getText(this, "Insert",
"Please input new data:",
QLineEdit::Normal,
"You are inserting new data.",
&isOK);
if (isOK) {
int row = listView->currentIndex().row();
model->insertRows(row, 1);
QModelIndex index = model->index(row);
model->setData(index, text);
listView->setCurrentIndex(index);
listView->edit(index);
}
}
insertData() QInputDialog::getText()
Qt
OK listView->currentIndex() QListView
QModelIndex
row() int
insertRows()
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
currentIndex()
void MyListView::insertData()
{
bool isOK;
QString text = QInputDialog::getText(this, "Insert",
"Please input new data:",
QLineEdit::Normal,
"You are inserting new data.",
&isOK);
if (isOK) {
QModelIndex currIndex = listView->currentIndex();
model->insertRows(currIndex.row(), 1);
model->setData(currIndex, text);
listView->edit(currIndex);
}
}
void MyListView::deleteData()
{
if (model->rowCount() > 1) {
model->removeRows(listView->currentIndex().row(), 1);
}
}
removeRows()
insertRows() rowCount()
1
void MyListView::showData()
{
QStringList data = model->stringList();
QString str;
foreach(QString s, data) {
str += s + "\n";
}
QMessageBox::information(this, "Data", str);
}
QStringListModel
model/view
44 QFileSystemModel
QStringListModel
QFileSystemModelQFileSystemModel QStringListModel
QFileSystemModel
Qt Qt QStandardItemModel
QFileSystemModelQStandardItemModel
QFileSystemModel
QFileSystemModel
QTreeView QFileSystemModel
FileSystemWidget::FileSystemWidget(QWidget *parent) :
QWidget(parent)
{
model = new QFileSystemModel;
model->setRootPath(QDir::currentPath());
setLayout(layout);
setWindowTitle("File System Model");
connect(mkdirButton, SIGNAL(clicked()),
this, SLOT(mkdir()));
connect(rmButton, SIGNAL(clicked()),
this, SLOT(rm()));
}
QFileSystemModel
QTreeView QFileSystemModel
treeView
setRootIndex()
QDir::currentPath()
index()
QFileSystemModel
mkdir()
void FileSystemWidget::mkdir()
{
QModelIndex index = treeView->currentIndex();
if (!index.isValid()) {
return;
}
QString dirName = QInputDialog::getText(this,
tr("Create Directory"),
tr("Directory name"));
if (!dirName.isEmpty()) {
if (!model->mkdir(index, dirName).isValid()) {
QMessageBox::information(this,
tr("Create Directory"),
tr("Failed to create the directory"));
}
}
}
isValid()
rm()
void FileSystemWidget::rm()
{
QModelIndex index = treeView->currentIndex();
if (!index.isValid()) {
return;
}
bool ok;
if (model->fileInfo(index).isDir()) {
ok = model->rmdir(index);
} else {
ok = model->remove(index);
}
if (!ok) {
QMessageBox::information(this,
tr("Remove"),
tr("Failed to remove %1").arg(model->fileName(index)));
}
}
isDir()
QFileSystemModel
QFileSystemModel
QFileSystemWatcher
treeView->header()->setStretchLastSection(true);
treeView->header()->setSortIndicator(0, Qt::AscendingOrder);
treeView->header()->setSortIndicatorShown(true);
#if QT_VERSION >= 0x050000
treeView->header()->setSectionsClickable(true);
#else
treeView->header()->setClickable(true);
#endif
Qt
Qt4 Qt5
QStringListModel QFileSystemModel
45
model
model/view model Qt
QAbstractItemModel
QAbstractItemModel
model
model index
QModelIndex
QPersistentModelIndex
QModelIndex()
index() parent
A C
A B
B 1 0 A
1 0 parent
Qt::DisplayRole
Qt::ItemDataRole
o index()
index()
QFileSystemModel
QFileSystemModel QFileSystemModel
index() rowCount()
index() 0
parentIndex data()
QVariant
QString
o rowCount() columnCount()
o
o QModelIndex()
46
model/view
QAbstractItemModel QAbstractItemView
QTableView QTreeView
QHeaderView QFileSystemModel
QAbstractItemModel::headerData() label
QHeaderView
QStringList data;
data << "0" << "1" << "2";
model = new QStringListModel(this);
model->setStringList(data);
listView = new QListView(this);
listView->setModel(model);
Model-View-ControllerMVCmodel/view
QStyledItemDelegate
o createEditor()
o setEditorData()
o updateEditorGeometry()
o setModelData()
createEditor()parent
setEditorData() Qt::EditRole
toInt()editor
QSpinBox
setModelData()
QSpinBox
QStyledItemDelegate closeEditor()
closeEditor()
QAbstractItemModel
QListView
listView->setItemDelegate(new SpinBoxDelegate(listView));
new Qt
47
Qt model/view
Qt
Qt
Qt QItemSelectionModel
F2
QItemSelectionModel
QListViewQTreeView QTableView
selectionModel()
setSelectionModel()
QItemSelection
32
QTableView
QItemSelection
QItemSelection
select()
Qt
QItemSelectionModel::SelectionFlags
QItemSelectionModel::Select
selectedIndexes()
foreach(index, indexes) {
QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());
model->setData(index, text);
}
selectionChanged()
selectionChanged()
currentChanged() selectionChanged()
QItemSelectionModel::SelectionFlag
select()
QItemSelectionModel::Select
QItemSelectionModel::Toggle
QItemSelectionModel::Deselect
QItemSelectionModel::Toggle
QItemSelection toggleSelection;
selectionModel->select(toggleSelection, QItemSelectionModel::Toggle);
QItemSelection columnSelection;
columnSelection.select(topLeft, bottomRight);
selectionModel->select(columnSelection,
QItemSelectionModel::Select |
QItemSelectionModel::Columns);
QItemSelection rowSelection;
rowSelection.select(topLeft, bottomRight);
selectionModel->select(rowSelection,
QItemSelectionModel::Select | QItemSelectionModel::Rows);
QItemSelectionModel::Rows QItemSelectionModel::Columns
QItemSelectionModel::Current
QItemSelectionModel::Clear
48 QSortFilterProxyModel
Qt
QStringListModel QFileSystemModel
Qt
QSortFilterProxyModel
QSortFilterProxyModel
QSortFilterProxyModel
Excel
Qt
QSortFilterProxyModel
class SortView : public QWidget
{
Q_OBJECT
public:
SortView();
private:
QListView *view;
QStringListModel *model;
QSortFilterProxyModel *modelProxy;
QComboBox *syntaxBox;
private slots:
void filterChanged(const QString &text);
};
SortView QWidget
SortView::SortView()
{
model = new QStringListModel(QColor::colorNames(), this);
connect(filterInput, SIGNAL(textChanged(QString)),
this, SLOT(filterChanged(QString)));
}
QStringListModel Qt
QColor::colorNames() QSortFilterProxyModel
model model
FilterKeyColumn 0
QStringListModel
QSortFilterProxyModel setSourceModel()
QStringListModel model
QListView QSortFilterProxyModel model
syntaxBox
JavaC# Python Qt
C++ boost
QregExp::RegExp
Qt
QRegExp::RegExp2 Qt4 QRegExp::RegExp2 Qt5
Unix shell
filterChanged()
QComboBox QRegExp::PatternSyntax
QLineEdit
gr[ae]y
g r
a e y
49
model/view QListView
QTableView QTreeView
Qt
QAbstractView QAbstractItemModel
Qt
QAbstarctListModel QAbstractTableModel
QAbstractListModel QAbstractTableModel
QAbstractItemModel
QAbstractItemModel
10000 100
QAbstractTableModel
CurrencyModel::CurrencyModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
rowCount() columnCount()
map
headerData()
currencyAt() section
QVariant currencyAt()
string int
Qt QVariant
to int
QVariant QVariant::toInt() union union
Qt QVariant union
setCurrencyMap()
currencyMap beginResetModel()
endResetModel()
data()
if (role == Qt::TextAlignmentRole) {
return int(Qt::AlignRight | Qt::AlignVCenter);
} else if (role == Qt::DisplayRole) {
QString rowCurrency = currencyAt(index.row());
QString columnCurrency = currency At(index.column());
if (currencyMap.value(rowCurrency) == 0.0) {
return "####";
}
double amount = currencyMap.value(columnCurrency)
/ currencyMap.value(rowCurrency);
return QString("%1").arg(amount, 0, 'f', 4);
}
return QVariant();
}
data() QModelIndex
role QVariant
index QVariant
role Qt::TextAlignmentRole int(Qt::AlignRight |
Qt::AlignVCenter) Qt::DisplayRole
ifelse
if int else QString QVariant
main()
QTableView view;
CurrencyModel *model = new CurrencyModel(&view);
model->setCurrencyMap(data);
view.setModel(model);
view.resize(400, 300);
view.show();
return a.exec();
}
50
CurrencyModel
Qt model/view delegate
flag
flags()
1.0000
Qt::ItemFlags CurrencyModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if (index.row() != index.column()) {
flags |= Qt::ItemIsEditable;
}
return flags;
}
index.row() != index.column()
Qt::ItemIsEditable QAbstractItemModel::flags(index) | Qt::ItemIsEditable
Qt
setData()
currencyMap["CNY"]/currencyMap["HKD"]
currencyMap["HKD"]
index
Qt::EditRole Qt::EditRole
Qt::ItemIsUserCheckable
Qt::CheckStateRoleQt
dataChanged()
dataChanged()
true false
data()
if (role == Qt::TextAlignmentRole) {
return int(Qt::AlignRight | Qt::AlignVCenter);
} else if (role == Qt::DisplayRole || role == Qt::EditRole) {
QString rowCurrency = currencyAt(index.row());
QString columnCurrency = currencyAt(index.column());
if (currencyMap.value(rowCurrency) == 0.0) {
return "####";
}
double amount = currencyMap.value(columnCurrency)
/ currencyMap.value(rowCurrency);
return QString("%1").arg(amount, 0, 'f', 4);
}
return QVariant();
}
role == Qt::EditRole
EditRole Qt
Qt
model / view
51
C++ GUI Programming with Qt 4, 2nd Edition
o Node
o BooleanModel
o BooleanParser
o BooleanWindow
Node
class Node
{
public:
enum Type { Root, OrExpression, AndExpression, NotExpression, Atom,
Identifier, Operator, Punctuator };
Type type;
QString str;
Node *parent;
QList<Node *> children;
};
Node cpp
Node::~Node()
{
qDeleteAll(children);
}
BooleanParser
BooleanParser
// booleanparser.h
class BooleanParser
{
public:
Node *parse(const QString &expr);
private:
Node *parseOrExpression();
Node *parseAndExpression();
Node *parseNotExpression();
Node *parseAtom();
Node *parseIdentifier();
void addChild(Node *parent, Node *child);
void addToken(Node *parent, const QString &str, Node::Type type);
bool matchToken(const QString &str) const;
QString in;
int pos;
};
// booleanparser.cpp
Node *BooleanParser::parse(const QStrin g &expr)
{
in = expr;
in.replace(" ", "");
pos = 0;
Node *BooleanParser::parseOrExpression()
{
Node *childNode = parseAndExpression();
if (matchToken("||")) {
Node *node = new Node(Node::OrExpression);
addChild(node, childNode);
while (matchToken("||")) {
addToken(node, "||", Node::Operator);
addChild(node, parseAndExpression());
}
return node;
} else {
return childNode;
}
}
Node *BooleanParser::parseAndExpression()
{
Node *childNode = parseNotExpression();
if (matchToken("&&")) {
Node *node = new Node(Node::AndExpression);
addChild(node, childNode);
while (matchToken("&&")) {
addToken(node, "&&", Node::Operator);
addChild(node, parseNotExpression());
}
return node;
} else {
return childNode;
}
}
Node *BooleanParser::parseNotExpression()
{
if (matchToken("!")) {
Node *node = new Node(Node::NotExpression);
while (matchToken("!"))
addToken(node, "!", Node::Operator);
addChild(node, parseAtom());
return node;
} else {
return parseAtom();
}
}
Node *BooleanParser::parseAtom()
{
if (matchToken("(")) {
Node *node = new Node(Node::Atom);
addToken(node, "(", Node::Punctuator);
addChild(node, parseOrExpression());
addToken(node, ")", Node::Punctuator);
return node;
} else {
return parseIdentifier();
}
}
Node *BooleanParser::parseIdentifier()
{
int startPos = pos;
while (pos < in.length() && in[pos].isLetterOrNumber())
++pos;
if (pos > startPos) {
return new Node(Node::Identifier,
in.mid(startPos, pos - startPos));
} else {
return 0;
}
}
BooleanParser
BooleanParser
MVC
BooleanParser
Node BooleanParser
model/view
QAbstractItemModel
BooleanParser
BooleanParser
Node * parse(const QString &)
pos 0pos
0 Root
BE BE OR BE
| BE AND BE
| NOT BE
| (BE)
| RE | true | false
RE RE RELOP RE | (RE) | E
E E op E | -E | (E) | Identifier | Number
BE BE OR BE
| BE AND BE
| NOT BE
| (BE)
| Identifier
1.
( )( )
OR parseOrExpression()
2. ! ( )
parseIdentifier() pos
startPos pos startPos
pos startPos + 1
BooleanModel
private:
Node *nodeFromIndex(const QModelIndex &index) const;
Node *rootNode;
};
BooleanModel::BooleanModel(QObject *parent)
: QAbstractItemModel(parent)
{
rootNode = 0;
}
BooleanModel::~BooleanModel()
{
delete rootNode;
}
QAbstractItemModel index()
QAbstractTableModel QAbstractListModel
QAbstractItemModel
rowCount() columnCount()
parent()
data()
headerData()
if (index.column() == 0) {
switch (node->type) {
case Node::Root:
return tr("Root");
case Node::OrExpression:
return tr("OR Expression");
case Node::AndExpression:
return tr("AND Expression");
case Node::NotExpression:
return tr("NOT Expression");
case Node::Atom:
return tr("Atom");
case Node::Identifier:
return tr("Identifier");
case Node::Operator:
return tr("Operator");
case Node::Punctuator:
return tr("Punctuator");
default:
return tr("Unknown");
}
} else if (index.column() == 1) {
return node->str;
}
return QVariant();
}
index index
BooleanWindow
BooleanWindow::BooleanWindow()
{
label = new QLabel(tr("Boolean expression:"));
lineEdit = new QLineEdit;
setWindowTitle(tr("Boolean Parser"));
}
52
Drag and Drop DnD
Qt
dragEnterEvent() dropEvent()
MainWindow::MainWindow(QWidget *p arent)
: QMainWindow(parent)
{
textEdit = new QTextEdit;
setCentralWidget(textEdit);
textEdit->setAcceptDrops(false);
setAcceptDrops(true);
setWindowTitle(tr("Text Editor"));
}
MainWindow::~MainWindow()
{
}
QTextEdit QTextEdit
MainWindow
MainWindow QTextEdit setAcceptDrops()
false MainWindow setAcceptDrops() true
MainWindow QTextEdit
dragEnterEvent()
acceptProposeAction()
Qt
if (readFile(fileName)) {
setWindowTitle(tr("%1 - %2").arg(fileName, tr("Drag File")));
}
}
dropEvent() QMimeData::urls()
QUrl
readFile()
ProjectListWidget QListWidget
ProjectListWidget
ProjectListWidget::ProjectListWidget(QWidget *parent)
: QListWidget(parent)
{
setAcceptDrops(true);
}
setAcceptDrops() ProjectListWidget
void ProjectListWidget::performDrag()
{
QListWidgetItem *item = currentItem();
if (item) {
QMimeData *mimeData = new QMimeData;
mimeData->setText(item->text());
mousePressEvent()
mouseMoveEvent() if
manhattanLength()
event.pos() - startPos mousePressEvent()
startPos event.pos()
QApplication::startDragDistance()
QApplication::startDragDistance()
4px
ProjectListWidget
53
QMimeData
QMimeData::setText() QMimeData::urls() URL
QMimeData
1. QByteArray QMimeData::setData()
QMimeData QMimeData::data()
3. QMimeData
QByteArray
QMimeData
CSV
QPoint startPos;
};
QTableWidget QTableView
DataTableWidget::DataTableWidget(QWidget *parent)
: QTableWidget(parent)
{
setAcceptDrops(true);
setSelectionMode(ContiguousSelection);
setColumnCount(3);
setRowCount(5);
}
setAcceptDrops()
mousePressEvent()
mouseMoveEvent()dragEnterEvent() dragMoveEvent()
performDrag()
void DataTableWidget::performDrag()
{
QString selectedString = selectionText();
if (selectedString.isEmpty()) {
return;
}
selectionText()
QMimeData HTML CSV CSV
QByteArray QDrag QMimeData
exec()exec()
QMimeData parent
delete setMimeData() QDrag
parent QDrag QDrag
QMimeData delete
QMimeData
dropEvent() CSV
fromCsv()
toHtml()
Qt4 Qt5
Qt4 Qt5 fromCsv()
MainWindow
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
topTable = new DataTableWidget(this);
QStringList headers;
headers << "ID" << "Name" << "Age";
topTable->setHorizontalHeaderLabels(headers);
topTable->setItem(0, 0, new QTableWidgetItem(QString("0001")));
topTable->setItem(0, 1, new QTableWidgetItem(QString("Anna")));
topTable->setItem(0, 2, new QTableWidgetItem(QString("20")));
topTable->setItem(1, 0, new QTableWidgetItem(QString("0002")));
topTable->setItem(1, 1, new QTableWidgetItem(QString("Tommy")));
topTable->setItem(1, 2, new QTableWidgetItem(QString("21")));
topTable->setItem(2, 0, new QTableWidgetItem(QString("0003")));
topTable->setItem(2, 1, new QTableWidgetItem(QString("Jim")));
topTable->setItem(2, 2, new QTableWidgetItem(QString("21")));
topTable->setItem(3, 0, new QTableWidgetItem(QString("0004")));
topTable->setItem(3, 1, new QTableWidgetItem(QString("Dick")));
topTable->setItem(3, 2, new QTableWidgetItem(QString("24")));
topTable->setItem(4, 0, new QTableWidgetItem(QString("0005")));
topTable->setItem(4, 1, new QTableWidgetItem(QString("Tim")));
topTable->setItem(4, 2, new QTableWidgetItem(QString("22")));
setCentralWidget(content);
setWindowTitle("Data Table");
}
shift
QMimeData
dataFormats
formats()
MIME
dragEvent()
qobject_cast
QTableWidget
if (tableData) {
const QTableWidget *otherTable = tableData->tableWidget();
QTableWidgetSelectionRange otherRange = tableData ->range();
// ...
event->acceptProposedAction();
} else if (event->mimeData()->hasFormat("text/csv")) {
QByteArray csvData = event->mimeData()->data("text/csv");
QString csvText = QString::fromUtf8(csvData);
// ...
event->acceptProposedAction();
}
QTableWidget::mouseMoveEvent(event);
}
54
Qt
ClipboardDemo::ClipboardDemo(QWidget *parent)
: QWidget(parent)
{
QVBoxLayout *mainLayout = new QVBoxLayout(this);
QHBoxLayout *northLayout = new QHBoxLayout;
QHBoxLayout *southLayout = new QHBoxLayout;
northLayout->addWidget(label);
northLayout->addWidget(editor);
southLayout->addWidget(copyButton);
southLayout->addWidget(pasteButton);
mainLayout->addLayout(northLayout);
mainLayout->addLayout(southLayout);
void ClipboardDemo::setClipboardContent()
{
QClipboard *board = QApplication::clipboard();
board->setText("Text from Qt Application");
}
void ClipboardDemo::getClipboardContent()
{
QClipboard *board = QApplication::clipboard();
QString str = board->text();
QMessageBox::information(NULL, "From clipboard", str);
}
QApplication::clipboard()
QClipboard API setText()
setImage() setPixmap()
text() image() pixmap()
QClipboard QMimeData
setMimeData()
X11
QClipboard::text() QClipboard::Selection
QClipboard dataChanged()
55
Qt QtSql SQL
SQL
NoSQL NoSQL
Qt model/view
model/view
Qt QSqlDatabase Qt drivers
API Qt
QMYSQL MySQL
QSQLITE2 SQLite 2
QSQLITE SQLite 3
Qt
Qt QSqlite Sqlite
Sqlite
Qt
SQL QSqlQuery
SQL QSqlTableModel
QSqlRelationalTableModel QSqlQuery
QSqlTableModel QSqlRelationalTableModel
QSqlDatabase::drivers();
QtSql Qt .pro
QT += sql
Qt coregui sql
Qt4 Qt5 .pro
Qt coregui sql 4
widgets
QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE",
QString("con%1").arg(dbName));
addDatabase()
QString("conn%1").arg(dbName)
QSQLITE
QSqlDatabase::defaultConnectionQt
sqlite
MySQL
QSqlDatabase::open() open()
QtSql lastError()
connect()
main() connect()
main() connect()
QSqlQuery SQL lastError()
QSqlQuery
addDatabase()
QSqlDatabase::defaultConnection
QSqlQuery
QSqlDatabase addDatabase()
QSqlQuery::isActive() QSqlQuery
true exec()
finish() clear()
QSqlQuery SELECT
connect() rollback()
SELECT
student
if (connect("demo.db")) {
QSqlQuery query;
query.prepare("INSERT INTO student (name, age) VALUES (?, ?)");
QVariantList names;
names << "Tom" << "Jack" << "Jane" << "Jerry";
query.addBindValue(names);
QVariantList ages;
ages << 20 << 23 << 22 << 25;
query.addBindValue(ages);
if (!query.execBatch()) {
QMessageBox::critical(0, QObject::tr("Database Error"),
query.lastError().text());
}
query.finish();
query.exec("SELECT name, age FROM student");
while (query.next()) {
QString name = query.value(0).toString();
int age = query.value(1).toInt();
qDebug() << name << ": " << age;
}
} else {
return 1;
}
demo.db
QSqlQuery::exec()
QSqlQuery::prepare() SQL ?
SQL SQL
names
ages QSqlQuery::addBindValue()
SQL names ages
QSqlQuery::execBatch() SQL
ODBC ? Oracle
query.bindValue(":name", names);
query.bindValue(":age", ages);
Oracle
bindValue()
:name
SELECT
QSqlQuery::next() true false
while QSqlQuery::value()
SELECT
QSqlDatabase::transaction()
QSqlDatabase::commit() QSqlDatabase::rollback()
QSqlDatabase::database()
56
SQL CREATESELECT
Qt SQL
QSqlTableModel
SQL QSqlTableModel
QSqlTableModel SQL
QSqlTableModel QListView
QTableView
QSqlTableModel SELECT
if (connect("demo.db")) {
QSqlTableModel model;
model.setTable("student");
model.setFilter("age > 20 and age < 25");
if (model.select()) {
for (int i = 0; i < model.rowCount(); ++i) {
QSqlRecord record = model.record(i);
QString name = record.value("name ").toString();
int age = record.value("age").toInt();
qDebug() << name << ": " << age;
}
}
} else {
return 1;
}
connect() QSqlTableModel
setTable()setFilter() WHERE
SQL
QSqlTableModel SQL
QSqlTableModel SELECT *
QSqlTableModel
QSqlTableModel model;
model.setTable("student");
int row = 0;
model.insertRows(row, 1);
model.setData(model.index(row, 1), "Cheng");
model.setData(model.index(row, 2), 24);
model.submitAll();
model.insertRows(row, 1); 0 1
setData() row
Cheng model.index(row, 1) model
row 1 submitAll()
SQL
QSqlTableModel model;
model.setTable("student");
model.setFilter("age = 25");
if (model.select()) {
if (model.rowCount() == 1) {
QSqlRecord record = model.record(0);
record.setValue("age", 26);
model.setRecord(0, record);
model.submitAll();
}
}
age = 25 age 26
0
setData()
if (model.select()) {
if (model.rowCount() == 1) {
model.setData(model.index(0, 2), 26);
model.submitAll();
}
}
age 3 2 id name
SQL
QSqlTableModel model;
model.setTable("student");
model.setFilter("age = 25");
if (model.select()) {
if (model.rowCount() == 1) {
model.removeRows(0, 1);
model.submitAll();
}
}
SQL
removeRows()
57
Qt QSqlQuery
QSqlTableModel model/view
model/view
QSqlTableModel
QSqlQuery view model
model QTableWidget
student
view->show();
} else {
return 1;
}
return a.exec();
}
connect()
id
model QTableView
resizeColumnsToContents()setEditTriggers()
QSqlTableModel
enum ColumnIndex
{
Column_ID = 0,
Column_Name = 1,
Column_Age = 2
};
view->show();
} else {
return 1;
}
return a.exec();
}
58
SQL
model/view Qt
city
city
student city
CREATE TABLE student (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR,
age INTEGER,
address INTEGER,
FOREIGN KEY(address) REFERENCES city(id));
Qt
INSERT INTO student (name, age, address) VALUES ('Tom', 24, 100);
city ID 100
Qt sqlite sqlite3 Qt
QSqlQuery
INSERT INTO student (name, age, address) VALUES ('Tom', 20, 2);
INSERT INTO student (name, age, address) VALUES ('Jack', 23, 1);
INSERT INTO student (name, age, address) VALUES ('Jane', 22, 4);
INSERT INTO student (name, age, address) VALUES ('Jerry', 25, 5);
model/view
City QSqlQuery
SQL SELECT
QSqlQueryQSqlRelationalTableModel
QSqlRelationalTableModel QSqlTableModel
city name
QComboBox
59 XML
Qt XML
o QXmlStreamReader XML
XML
XML Qt
o QXmlStreamWriter QXmlStreamReader
o XML
QXmlStreamReader Qt XML
QXmlStreamReader XML
XML
QXmlStreamReader readNext()
EndDocument -
XML
<doc>
<quote>Einmal ist keinmal</quote>
</doc>
readNext()
StartDocument
StartElement (name() == "doc")
StartElement (name() == "quote")
Characters (text() == "Einmal ist keinmal")
EndElement (name() == "quote")
EndElement (name() == "doc")
EndDocument
XML
QTreeWidget XML
<bookindex>
<entry term="sidebearings">
<page>10</page>
<page>34-35</page>
<page>307-308</page>
</entry>
<entry term="subtraction">
<entry term="of pictures">
<page>115</page>
<page>244</page>
</entry>
<entry term="of vectors">
<page>9</page>
</entry>
</entry>
</bookindex>
QTreeWidget *treeWidget;
QXmlStreamReader reader;
};
MainWindow
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setWindowTitle(tr("XML Reader"));
MainWindow::~MainWindow()
{
}
XML
readFile() QFile
QXmlStreamReader QXmlStreamReader
QFile while
StartElement bookindex
bookindex bookindex
raiseError() StartElement
readNext() readNext()
while XML readNext()
XML DTD
readNext() XML
XML DTD
while
readBookindexElement()
void MainWindow::readBookindexElement()
{
Q_ASSERT(reader.isStartElement() && reader.name() == "bookindex");
reader.readNext();
while (!reader.atEnd()) {
if (reader.isEndElement()) {
reader.readNext();
break;
}
if (reader.isStartElement()) {
if (reader.name() == "entry") {
readEntryElement(treeWidget->invisibleRootItem());
} else {
skipUnknownElement();
}
} else {
reader.readNext();
}
}
}
reader StartElement
bookindex readNext()
while EndElement StartElement entry
XML bookindex entry entry
readEntryElement()
reader.readNext();
while (!reader.atEnd()) {
if (reader.isEndElement()) {
reader.readNext();
break;
}
if (reader.isStartElement()) {
if (reader.name() == "entry") {
readEntryElement(item);
} else if (reader.name() == "page") {
readPageElement(item);
} else {
skipUnknownElement();
}
} else {
reader.readNext();
}
}
}
QTreeWidgetItem entry
QTreeWidget entry term
while EndElement StartElement
readEntryElement() readPageElement() entry
entry page
readPageElement()
page while
entry page
skipUnknownElement()
void MainWindow::skipUnknownElement()
{
reader.readNext();
while (!reader.atEnd()) {
if (reader.isEndElement()) {
reader.readNext();
break;
}
if (reader.isStartElement()) {
skipUnknownElement();
} else {
reader.readNext();
}
}
}
while
StartElement
main()
MainWindow w;
w.readFile("books.xml");
w.show();
60 DOM XML
DOM XML
DOM
XML
XML
<doc>
<quote>Scio me nihil scire</quote>
<translation>I know that I know nothing</translation>
</doc>
DOM
Document
|--Element(doc)
|--Element(quote)
| |--Text("Scio me nihil scire")
|--Element(translation)
|--Text("I know that I know nothing")
DOM Element
Element
Qt DOM QDom QDomElement
Element QDomText Text
Element Element EntityReference
TextCDATASectionProcessingInstruction Comment W3C
[Document]
<- [Element]
<- DocumentType
<- ProcessingInstrument
<- Comment
[Attr]
<- [EntityReference]
<- Text
[DocumentFragment] | [Element] | [EntityReference] | [Entity]
<- [Element]
<- [EntityReference]
<- Text
<- CDATASection
<- ProcessingInstrument
<- Comment
[]
books.xml
QTreeWidget DOM XML
Qt4 Qt5 .pro
QT += xml
MainWindow
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setWindowTitle(tr("XML DOM Reader"));
MainWindow::~MainWindow()
{
}
readFile()
QString errorStr;
int errorLine;
int errorColumn;
QDomDocument doc;
if (!doc.setContent(&file, false, &errorStr, &errorLine,
&errorColumn)) {
QMessageBox::critical(this, tr("Error"),
tr("Parse error at line %1, column %2: %3")
.arg(errorLine).arg(errorColumn).arg(errorStr));
return false;
}
parseBookindexElement(root);
return true;
}
readFile() QFile
QDomDocument
Document DOM QDomDocument setContent()
DOM setContent()
QDomDocument::setContent()
QDomDocument::documentElement() Document
Document bookindex
entry entry
nextSibling() if
entry firstChild() nextSibling()
QDomNode
toElement() QDomNode
QDomElement QDomElement tagName()
if
parseEntryElement()
entry entry entry
parsePageElement()
parsePageElement()
61 SAX XML
DOM XML
XML SAXSAX XML API DOM
Qt SAX SAX2 Java
DOMSAX
QXmlStreamReader Qt API SAX
SAX API SAX API Qt
SAX
Qt
<doc>
<quote>Gnothi seauton</quote>
</doc>
XML
startDocument()
startElement("doc")
startElement("quote")
characters("Gnothi seauton")
endElement("quote")
endElement("doc")
endDocument()
Handler
QXmlContentHandler
QXmlContentHandler
QXmlEntityResolverQXmlDTDHandlerQXmlErrorHandlerQXmlDeclHandler
QXmlLexicalHandler
QXmlContentHandler QXmlErrorHandler
Qt QXmlDefaultHandler
Qt
JavaJava
SAX
protected:
bool startElement(const QString &namespaceURI,
const QString &localName,
const QString &qName,
const QXmlAttributes &attributes);
bool endElement(const QString &namespaceURI,
const QString &localName,
const QString &qName);
bool characters(const QString &str);
bool fatalError(const QXmlParseException &exception);
private:
QTreeWidget *treeWidget;
QTreeWidgetItem *currentItem;
QString currentText;
};
MainWindow
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setWindowTitle(tr("XML Reader"));
MainWindow::~MainWindow()
{
}
readFile()
QFile file(fileName);
QXmlInputSource inputSource(&file);
QXmlSimpleReader reader;
reader.setContentHandler(this);
reader.setErrorHandler(this);
return reader.parse(inputSource);
}
XML
QXmlSimpleReader ContentHandler ErrorHandler
ContentHandler ErrorHandler
handlerparse() QXmlSimpleReader XML
endElement() startElement()
</entry> currentItem
currentItem <entry> </page>
currentText
SAX fatalError()
XML
62 XML
XML Qt
QXmlStreamReader XML XML
Qt
1. QXmlStreamWriter
2. DOM save()
3. QString XML
W3C
XML XML
DOM DOM
Qt QXmlStreamWriter XML
QXmlStreamWriter
XML
QFile file("bookindex.xml");
if (!file.open(QFile::WriteOnly | QFile::Text)) {
qDebug() << "Error: Cannot write file: "
<< qPrintable(file.errorString());
return false;
}
QXmlStreamWriter xmlWriter(&file);
xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("bookindex");
xmlWriter.writeStartElement("entry");
xmlWriter.writeAttribute("term", "sidebearings");
xmlWriter.writeTextElement("page", "10");
xmlWriter.writeTextElement("page", "34-35");
xmlWriter.writeTextElement("page", "307 -308");
xmlWriter.writeEndElement();
xmlWriter.writeStartElement("entry");
xmlWriter.writeAttribute("term", "subtraction");
xmlWriter.writeStartElement("entry");
xmlWriter.writeAttribute("term", "of pictures");
xmlWriter.writeTextElement("page", "115");
xmlWriter.writeTextElement("page", "224");
xmlWriter.writeEndElement();
xmlWriter.writeStartElement("entr y");
xmlWriter.writeAttribute("term", "of vectors");
xmlWriter.writeTextElement("page", "9");
xmlWriter.writeEndElement();
xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();
file.close();
if (file.error()) {
qDebug() << "Error: Cannot write file: "
<< qPrintable(file.errorString());
return false;
}
// ...
QXmlStreamWriter
setAutoFormatting() QXmlStreamWriter
QXmlStreamWriter::setAutoFormattingIndent()
write
write Start End
writeStartDocument() XML
writeStartDocument() writeEndDocument()
QXmlStreamWriter XML
xmlWriter.writeStartElement("entry");
xmlWriter.writeAttribute("term", "of vectors");
xmlWriter.writeTextElement("page", "9");
xmlWriter.writeEndElement();
entry term
of vectorswriteTextElement()
XML
//!!! Qt4
QTextStream out(&file);
out.setCodec("UTF-8");
out << "<doc>\n"
<< " <quote>" << Qt::escape(quoteText) << "</quote>\n"
<< " <translation>" << Qt::escape(translationText)
<< "</translation>\n"
<< "</doc>\n";
//!!! Qt5
QTextStream out(&file);
out.setCodec("UTF-8");
out << "<doc>\n"
<< " <quote>" << quoteText.toHtmlEscaped() << "</quote> \n"
<< " <translation>" << translationText.toHtmlEscaped()
<< "</translation>\n"
<< "</doc>\n";
XML
quoteText translationText XML
<> & Qt4 Qt::escape() Qt5
QString::toHtmlEscaped()
63 QJson JSON
XML XML
JSON JSON JSON XML
XML JSON XML XML
JSON
JSON
{
"encoding" : "UTF-8",
"plug-ins" : [
"python",
"c++",
"ruby"
],
"indent" : { "length" : 3, "use_space" : true }
}
#include "parser.h"
//////////
QJson::Parser parser;
bool ok;
QString json("{"
"\"encoding\" : \"UTF-8\","
"\"plug-ins\" : ["
"\"python\","
"\"c++\","
"\"ruby\""
"],"
"\"indent\" : { \"length\" : 3, \"use_space\" : true }"
"}");
QVariantMap result = parser.parse(json.toUtf8(), &ok).toMap();
if (!ok) {
qFatal("An error occurred during parsing");
exit (1);
}
JSON QVariant
// 1. QJson::Parser
QJson::Parser parser;
bool ok;
// 2. JSON json
QVariant result = parser.parse (json, &ok);
QVariantList people;
QVariantMap bob;
bob.insert("Name", "Bob");
bob.insert("Phonenumber", 123);
QVariantMap alice;
alice.insert("Name", "Alice");
alice.insert("Phonenumber", 321);
QJson::Serializer serializer;
bool ok;
QByteArray json = serializer.serialize(people, &ok);
if (ok) {
qDebug() << json;
} else {
qCritical() << "Something went wrong:" << serializer.errorMessage();
}
QJson::Serializer QJson::Parser
QJson::Serializer::serialize() QVariant JSON
QByteArray
public:
Person(QObject* parent = 0);
~Person();
private:
QString m_name;
int m_phoneNumber;
Gender m_gender;
QDate m_dob;
};
Person JSON
Person person;
person.setName("Flavio");
person.setPhoneNumber(123456);
person.setGender(Person::Male);
person.setDob(QDate(1982, 7, 12));
QJson::Parser parser;
QVariant variant = parser.parse(json);
Person person;
QObjectHelper::qvariant2qobject(variant.toMap(), &person);
64 QJsonDocument JSON
QJsonArray JSON
QJsonDocument JSON
QJsonObject JSON
QJsonParseError JSON
QJsonValue JSON
JSON QJsonDocument
QJsonDocument Qt5 Qt5
QString json("{"
"\"encoding\" : \"UTF-8\","
"\"plug-ins\" : ["
"\"python\","
"\"c++\","
"\"ruby\""
"],"
"\"indent\" : { \"length\" : 3, \"use_space\" : true }"
"}");
QJsonParseError error;
QJsonDocument jsonDocument = QJsonDocument::fromJson(json.toUtf8(), &error);
if (error.error == QJsonParseError::NoError) {
if (jsonDocument.isObject()) {
QVariantMap result = jsonDocument.toVariant().toMap();
qDebug() << "encoding:" << result["encoding"].toString();
qDebug() << "plugins:";
QJsonDocument JSON
// 1. QJsonParseError
QJsonParseError error;
// 2. QJsonDocument
QJsonDocument jsonDocument = QJsonDocument::fromJson(json.toUtf8(), &error);
// 3.
if (error.error == QJsonParseError::NoError) {
if (!(jsonDocument.isNull() || jsonDocument.isEmpty())) {
if (jsonDocument.isObject()) {
// ...
} else if (jsonDocument.isArray()) {
// ...
}
}
} else {
//
}
QVariant JSON
QVariantList people;
QVariantMap bob;
bob.insert("Name", "Bob");
bob.insert("Phonenumber", 123);
QVariantMap alice;
alice.insert("Name", "Alice");
alice.insert("Phonenumber", 321);
QJsonDocument
QJsonDocument::fromVariant() QJsonDocument QJsonDocument
QJsonDocument::fromBinaryData()
QJsonDocument::fromRawData() QJsonDocument
toJson() JSON
JSON QJsonDocument
JSON QJsonDocument setArray() setObject()
JSON
QVariant
Qt5 JSON
65 1
Qt
Qt
Qt QNetworkAccessManager
pro QT +=
network
QNetworkAccessManager
Qt API QNetworkAccessManager
API
Qt
QDialog::exec() QDialog::show()
QNetworkAccessManager
QNetworkAccessManager
QNetworkAccessManager
QNetworkAccessManager
QNetworkReply
QNetworkAccessManager
QNetworkAccessManager
OpenWeatherMap API
API
QNetworkAccessManager
NetWorker Qt5
Qt4
// !!! Qt5
#ifndef NETWORKER_H
#define NETWORKER_H
#include <QObject>
class QNetworkReply;
NetWorker instance()
class Private;
friend class Private;
Private *d;
NetWorker d d C++
C++ C++
Qt5.0
Qt5.1
Qt4 Qt5
NetWorker
class NetWorker::Private
{
public:
Private(NetWorker *q) :
manager(new QNetworkAccessManager(q))
{}
QNetworkAccessManager *manager;
};
Private NetWorker
NetWorker::Private QNetworkAccessManager *
QNetworkAccessManager NetWorker::Private NetWorker
QNetworkAccessManager parent NetWorker
QNetworkAccessManager NetWorker::Private
QObject
NetWorker *NetWorker::instance()
{
static NetWorker netWorker;
return &netWorker;
}
NetWorker::NetWorker(QObject *parent) :
QObject(parent),
d(new NetWorker::Private(this))
{
connect(d->manager, &QNetworkAccessManager::finished,
this, &NetWorker::finished);
}
NetWorker::~NetWorker()
{
delete d;
d = 0;
}
d
QNetworkAccessManager finished()
QNetworkAccessManager finished()NetWorker
finished() d NetWorker::Private
QObject delete
get() URL
QNetworkAccessManager QNetworkAccessManager
QNetworkAccessManager
OpenWeatherMap API
66 2
NetWorker C++
http://api.openweathermap.org/data/2.5/weather?q=Beijing,cn&mode=json&units=metric&lang=z
h_cn
q Beijing,cn
units metric
lang zh_cn
JSON
{"coord":{"lon":116.397232,"lat":39.907501},"sys":{"country":"CN","sunrise":1
381530122,"sunset":1381570774},"weather":[{"id":800,"main":"Clear","descripti
on":"","icon":"01d"}],"base":"gdps
stations","main":{"temp":20,"pressure":1016,"humidity":34,"temp_min":20,"temp
_max":20},"wind":{"speed":2,"deg":50},"clouds":{"all":0},"dt":1381566600,"id"
:1816670,"name":"Beijing","cod":200}
JSON dttemp
pressurehumidityweather WeatherInfo
class WeatherDetail
{
public:
WeatherDetail();
~WeatherDetail();
private:
class Private;
friend class Private;
Private *d;
};
class WeatherInfo
{
public:
WeatherInfo();
~WeatherInfo();
private:
class Private;
friend class Private;
Private *d;
};
WeatherInfo WeatherDetail
setter getter
private:
class Private;
friend class Private;
Private *d;
};
d
MainWindow::Private
class MainWindow::Private
{
public:
Private()
{
netWorker = NetWorker::instance();
}
netWorker->get(QString("http://api.openweathermap.org/data/2.5/weather?q=%1&m
ode=json&units=metric&lang=zh_cn").arg(cityName));
}
NetWorker *netWorker;
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
d(new MainWindow::Private)
{
QComboBox *cityList = new QComboBox(this);
cityList->addItem(tr("Beijing"), QLatin1String("Beijing,cn"));
cityList->addItem(tr("Shanghai"), QLatin1String("Shanghai,cn"));
cityList->addItem(tr("Nanjing"), QLatin1String("Nanjing,cn"));
QLabel *cityLabel = new QLabel(tr("City: "), this);
QPushButton *refreshButton = new QPushButton(tr("Refresh"), this);
QHBoxLayout *cityListLayout = new QHBoxLayout;
cityListLayout->setDirection(QBoxLayout::LeftToRi ght);
cityListLayout->addWidget(cityLabel);
cityListLayout->addWidget(cityList);
cityListLayout->addWidget(refreshButton);
detail->setDesc(wm[QLatin1String("description")].toString());
detail->setIcon(wm[QLatin1String("icon")].toString());
details.append(detail);
}
weather.setDetails(details);
cityNameLabel->setText(weather.cityName());
dateTimeLabel->setText(weather.dateTime().toString(Qt::DefaultLocaleLongDate)
);
}
} else {
QMessageBox::critical(this, tr("Error"), error.errorString());
}
reply->deleteLater();
});
connect(refreshButton, &QPushButton::clicked, [=] () {
d->fetchWeather(cityList->itemData(cityList->currentIndex()).toString());
});
}
MainWindow::~MainWindow()
{
delete d;
d = 0;
}
MainWindow
detail->setDesc(wm[QLatin1String("description")].toString());
detail->setIcon(wm[QLatin1String("icon")].toString());
details.append(detail);
}
weather.setDetails(details);
cityNameLabel->setText(weather.cityName());
dateTimeLabel->setText(weather.dateTime().toString(Qt::DefaultLocaleLongDate)
);
}
} else {
QMessageBox::critical(this, tr("Error"), error.errorString());
}
reply->deleteLater();
});
connect(refreshButton, &QPushButton::clicked, [=] () {
d->fetchWeather(cityList->itemData(cityList->currentIndex()).toString());
});
67 3
NetWorker
WeatherDetail icon
OpenWeatherMap API
icon JSON
{"coord":{"lon":116.397232,"lat":39.907501},"sys":{"country":"CN","sunrise":1
381530122,"sunset":1381570774},"weather":[{"id":800,"main":"Clear","descripti
on":"","icon":"01d"}],"base":"gdps
stations","main":{"temp":20,"pressure":1016,"humidity":34,"temp_min":20,"temp
_max":20},"wind":{"speed":2,"deg":50},"clouds":{"all":0},"dt":1381566600,"id"
:1816670,"name":"Beijing","cod":200}
icon:01d 01d
http://openweathermap.org/img/w/01d.png
NetWorker finished()
finished() Lambda
finished()
...
class MainWindow::Private
{
public:
Private(MainWindow *q) :
mainWindow(q)
{
netWorker = NetWorker::instance();
}
NetWorker *netWorker;
MainWindow *mainWindow;
QMap<QNetworkReply *, RemoteRequest> replyMap;
};
MainWindow::Private QMap
fetchWeather() fetchIcon() NetWorker::get()
RemoteRequest
enum RemoteRequest {
FetchWeatherInfo,
FetchWeatherIcon
};
detail->setDesc(wm[QLatin1String("description")].toString());
detail->setIcon(wm[QLatin1String("icon")].toString());
details.append(detail);
d->fetchIcon(detail->icon());
}
weather.setDetails(details);
cityNameLabel->setText(weather.cityName());
dateTimeLabel->setText(weather.dateTime().toString(Qt::DefaultLocaleLongDate)
);
}
} else {
QMessageBox::critical(this, tr("Error"), error.errorString());
}
break;
}
case FetchWeatherIcon:
{
QHBoxLayout *weatherDetailLayout = (QHBoxLayout
*)weatherLayout->itemAt(2)->layout();
QLabel *iconLabel = (QLabel *)weatherDetailLayout->itemAt(1)->widget();
QPixmap pixmap;
pixmap.loadFromData(reply->readAll());
iconLabel->setPixmap(pixmap);
break;
}
}
reply->deleteLater();
});
MainWindow::Private reply
switch FetchWeatherInfo
foreach WeatherDetail
d->fetchIcon(detail->icon()) FetchWeatherIcon
QHBoxLayout itemAt() label
reply
68 4
QNetworkAccessManager
QNetworkAccessManager
API
QNetworkAccessManager
GUI
Java Java Socket
QNetworkAccessManager
QNetworkAccessManager
Refresh Refresh
Qt
QNetworkAccessManager
GUI
GUI QNetworkAccessManager
69
Qt QProcess
//!!! Qt5
QString program = "C:/Windows/System32/cmd.exe";
QStringList arguments;
arguments << "/c" << "dir" << "C: \\";
QProcess *cmdProcess = new QProcess; cmdProcess->start(program, arguments);
QObject::connect(cmdProcess, &QProcess::readyRead, [=] () {
QTextCodec *codec = QTextCodec::codecForName("GBK");
QString dir = codec->toUnicode(cmdProcess->readAll());
qDebug() << dir;
});
Qt5 Windows Qt
C SYSTEM
EA62-24AB
C:\
Windows 8.1 64
programarguments
QProcess::start() setProgram() setArguments()
QProcess Starting QProcess Running
started()QProcess NotRunning
finished() finished()
QProcess error()
stdoutstderr
setReadChannel()
QProcess readReady()QProcess
readyReadStandardOutput()
readyReadStandardError() readReady()
Windows Windows GBK
QProcess
QProcess QProcess
QProcess QProcess
setProcessChannelMode() MergedChannels
QProcess setEnvironment()
setWorkingDirectory()
QNetworkAccessManager
QNetworkAccessManager QProcess
o waitForStarted()
o waitForReadyRead()
o waitForBytesWritten()
o waitForFinished()
QApplication::exec()
70
Inter-Process
CommunicationIPC
Qt
1. shared memory Qt
2. TCP/IP
C/S Qt QNetworkAccessManager
IPC TCP/IP
QNetworkAccessManager
QTcpSocket
Qt QSharedMemory QSharedMemory
QSharedMemory Qt
QSharedMemory
QSharedMemory create()
trueQt
attach
IPC IPC
o WindowsQSharedMemory
QSharedMemory Windows
o UnixQSharedMemory
QSharedMemory Unix
Windows
QSharedMemory
o HP-UX HP-UX
QSharedMemory
Qt
Qt5Qt4
//!!! Qt5
class QSharedMemory;
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QSharedMemory *sharedMemory;
};
MainWindow sharedMemory
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
sharedMemory(new QSharedMemory(KEY_SHARED_MEMORY, this))
{
QWidget *mainWidget = new QWidget(this);
QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget);
setCentralWidget(mainWidget);
sharedMemory
Key QSharedMemory
QBuffer buffer;
QDataStream out(&buffer);
buffer.open(QBuffer::ReadWrite);
out << pixmap;
QBuffer
Qt Qt
QSharedMemory::setNativeKey()
native keyQSharedMemory::lock()
IPC
QQ QQ QQ
71
CPU
Qt QThread
///!!! Qt5
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget *widget = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout;
widget->setLayout(layout);
QLCDNumber *lcdNumber = new QLCDNumber(this);
layout->addWidget(lcdNumber);
QPushButton *button = new QPushButton(tr("Start"), this);
layout->addWidget(button);
setCentralWidget(widget);
LCD
2000000000
LCD
QTimer
Qt UI
QApplication::exec()
UI
QThread
///!!! Qt5
class WorkerThread : public QThread
{
Q_OBJECT
public:
WorkerThread(QObject *parent = 0)
: QThread(parent)
{
}
protected:
void run()
{
for (int i = 0; i < 1000000000; i++);
emit done();
}
signals:
void done();
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget *widget = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout;
widget->setLayout(layout);
lcdNumber = new QLCDNumber(this);
layout->addWidget(lcdNumber);
QPushButton *button = new QPushButton(tr("Start"), this);
layout->addWidget(button);
setCentralWidget(widget);
Qt
Qt Qt
QObject
72
QThread
Qt Wiki
o Reentrant
Reentrant means
that all the functions in the referenced class can be called simultaneously by multiple threads,
provided that each invocation of the functions reference unique data. C++
o Thread-safe
Threadsafe means
that all the functions in the referenced class can be called simultaneously by multiple threads
even when each invocation references shared data.
Qt Qt
QEvent
QObject QObject::event()
o QKeyEvent QMouseEvent
o QTimerEvent QObject
o QChildEvent QObject Qt
while (is_active)
{
while (!event_queue_is_empty) {
dispatch_next_event();
}
wait_for_more_events();
}
QCoreApplication::exec()
QCoreApplication::exit() QCoreApplication::quit()
while
wait_for_more_events()
wait_for_more_events()
wait_for_more_events()
o socket
o timer
select(2)
Qt select()
QEvent
o QWidget::paintEvent() QPaintEvent
QWidget::update()
o select(2)
Qt
o QTcpSocketQUdpSocket QTcpServer
read() write()
waitFor
QNetworkAccessManager
API
QNetworkAccessManager
Button
Worker Worker
main() QApplication::exec()
Qt QMouseEvent event()
QApplication::notify()
event() QWidget::event()
Button::mousePressEvent() Button::clicked()
Worker::doWork()
worker
Worker::doWork()
QPaintEvent
QCoreApplication::processEvents()QCoreApplication::processEvents()
QEventLoop
QEventLoop::exec() QEventLoop::quit()
QEventLoop eventLoop;
connect(netWorker, &NetWorker::finished,
&eventLoop, &QEventLoop::quit);
QNetworkReply *reply = netWorker->get(url);
replyMap.insert(reply, FetchWeatherInfo);
eventLoop.exec();
QNetworkReply API
QEventLoop
Worker::doWork() QCoreApplication::processEvents()
Worker::doWork()
QCoreApplication::processEvents()
QEventLoop::ExcludeUserInputEvents
QObject::deleteLater()
deleteLater()
QDialog::exec() deleteLater()
QEventLoop Qt 4.7.3
deleteLater()
Qt
73 Qt
QThread Qt
Qt 2000 9 22 Qt 2.2
Qt
QThreadQt 4.0
Qt
QThread Qt Qt
QThread
QThread
QThread::run()
QRunnable
QRunnable
QRunnable::run()
QRunnable QObject
mutex
QThread QRunnableQtConcurrent
QtConcurrent QFuture
//
QFuture QtConcurrent::run()
QFuture QtConcurrent::mappedReduced()
QFutureWatcher QFuture QFutureWatcher
QFuture QObject
API
//
74 QObject
QObject
Qt
QCoreApplication::exec()QThread
main()
QCoreApplication::exec()
QCoreApplication::exec() main()
GUI GUI
QThread QThread::run() QThread::exec()
Qt 4.4 QThread::run()
QThread::exec() QCoreApplication QThread QThread::quit()
QThread::exit()
QObjects
private:
QObject obj;
QObject *otherObj;
QScopedPointer yetAnotherObj;
};
QObject::thread() QObject
QCoreApplication QObject
QCoreApplication QThread
QCoreApplication::postEvent()
QObject
QObject
delete
QObject QObject::deleteLater()
Qt
QObject
o parent QObject::moveToThread()
o QThread QThread
QThread
Qt QThread
delete QThread::run()
Qt
moc Q_INVOKABLE
QMetaObject::invokeMethod()
QMetaObject::invokeMethod(object, "methodName",
Qt::QueuedConnection,
Q_ARG(type1, arg1),
Q_ARG(type2, arg2));
qRegisterMetaType() Qt
QObject::connect()
o Qt::DirectConnection
o Qt::QueuedConnection
o Qt::BlockingQueuedConnection
o Qt::AutoConnection
Qt
Qt
/* ... */
Thread thread;
Object obj;
QObject::connect(&thread, SIGNAL(aSignal()), &obj, SLOT(aSlot()));
thread.start();
aSignal() Thread
Object Object Thread
/* ... */
Thread thread;
Object obj;
QObject::connect(&obj, SIGNAL(aSignal()), &thread, SLOT(aSlot()));
thread.start();
obj.emitSignal();
Thread
moveToThread(this)
class Thread : public QThread {
Q_OBJECT
public:
Thread() {
moveToThread(this); //
}
/* ... */
};
Thread
QThread
QThread
QObject QObject::moveToThread()
/* ... */
QThread *thread = new QThread;
Worker *worker = new Worker;
connect(obj, SIGNAL(workReady()), worker, SLOT(doWork()));
worker->moveToThread(thread);
thread->start();
75
o QThread
o moveToThread(this)
o QThread
o QThread QThread
QThread
moveToThread(this)
o QThread::terminate()
o QThread::wait()
o QThread
finished() deleteLater()
API
API API
API
n
CPU
QThread::idealThreadCount() CPU
CPU
CPU
WebKit QNetworkAccessManagerWebKit
Qt QWebView WebKit
QNetworkAccessManager Qt HTTP
Qt 4.8
QNetworkAccessManager QNetworkReply
socket
socket socket Qt
WebKit WebKit
o WebKit
o WebKit
o
QNetworkAccessManager socket
//
while (condition) {
doWork();
sleep(1); // C sleep(3)
}
//
class Thread : public QThread {
protected:
void run() {
while (condition) {
// condition
doWork();
sleep(1); // QThread::sleep()
}
}
};
QTimer 1s doWork()
doWork()
socket->connect(host);
socket->waitForConnected();
data = getData();
socket->write(data);
socket->waitForBytesWritten();
socket->waitForReadyRead();
socket->read(response);
reply = process(response);
socket->write(reply);
socket->waitForBytesWritten();
/* ... */
waitFor*()
UI
result = process_one_thing();
if (result->something()) {
process_this();
} else {
process_that();
}
wait_for_user_input();
input = read_user_input();
process_user_input(input);
/* ... */
<code>connectToHost()</code>
<code>connected()</code>
ACK
NACK
Qt
QStateMachine
source
socket QAbstractSocket::connected() QIODevice::readyRead()
QAbstractSocket::error()
GUI
QMetaObject::invokeMethod() Qt::QueuedConnection
Q_INVOKABLE
qRegisterMetaType() Qt
//
76 QML QtQuick 2
Qt C++
C++ Qt 5
Qt 5 Qt 4.7 Qt
QMLQt Meta Language Qt Modeling Language C++
Qt Quick QML
QML JavaScript Qt 5 QML C++
Qt Qt 5 C++ Qt
QML QML C++ QML
V8Qt 5.2 QML V4
Nokia Qt 4.7 QML
Qt 5 QML
QML QML
QML
QML QML
Qt Quick Qt Quick 2 Qt 4.x Qt Quick 1
qtquick2applicationviewer Qt Creator
QML Application
Viewer QML
main.qml
Rectangle {
width: 360
height: 360
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
}
QML import declaration
JavaScript
QML QML
360
77 QML
QML
x y Graphics View Framework
QML
// rectangle.qml
import QtQuick 2.0
// Rectangle
Rectangle {
//
id: root // <name>: <value>
width: 120; height: 240
color: "#D8D8D8" //
//
Image {
id: rocket
x: (parent.width - width)/2; y: 40 // parent
source: 'assets/rocket.png'
}
//
Text {
//
y: rocket.y + rocket.height + 20 // id
width: root.width // id
horizontalAlignment: Text.AlignHCenter
text: 'Rocket'
}
}
QML JSON
Text {
// (1)
id: thisLabel
// (2) xy
x: 24; y: 16
// (3)
height: 2 * width
// (4)
property int times: 24
// (5)
property alias anotherTimes: times
// (6)
text: "Greetings " + times
// (7)
font.family: "Ubuntu"
font.pixelSize: 24
// (8) KeyNavigation
KeyNavigation.tab: otherLabel
// (9)
onHeightChanged: console.log('height:', height)
// focus
focus: true
// focus
color: focus?"red":"black"
}
id QML id
QML id
id C++ id
C++ id
id aElement.id
id QML QML
dynamic-scoping id
id id id
id
height: 2
* widthheight width width height
width text int
QML property
// MyLabel.qml
import QtQuick 2.0
Text {
default property var defaultText
text: "Hello, " + defaultText.text
}
MyLabel
MyLabel {
Text { text: "world" }
}
MyLabel.qml QML
MyLabel MyLabel Text MyLabel
defaultText
MyLabel {
defaultTextText { text: "world" }
}
data
data
id
font
<Element>.<property>: <value>
on + + Changed
height onHeightChanged
QML JavaScript
Text {
id: label
x: 24; y: 24
//
property int spacePresses: 0
text: "Space pressed: " + spacePresses + " times"
// (1)
onTextChanged: console.log("text changed to:", text)
// focus
focus: true
// (2) JavaScript
Keys.onSpacePressed: {
increment()
}
// Esc
Keys.onEscapePressed: {
label.text = ''
}
// (3) JavaScript
function increment() {
spacePresses = spacePresses + 1
}
}
Text textChanged on +
Text textChanged onTextChanged
onSpacePressed
JavaScript
QML JavaScript
78 QML
QML
Rectangle Timer
ItemRectangle TextImage
MouseArea
Item
ItemItem
x y width height z
Item
Item
Item HTML div
Rectangle {
id: rect
width: 100
height: 150
color: "lightsteelblue"
border {
color: "#FF0000"
width: 4
}
radius: 8
}
QML #
SVG
Rectangle {
width: 100
height: 150
gradient: Gradient {
GradientStop { position: 0.0; color: "red" }
GradientStop { position: 0.33; color: "yellow" }
GradientStop { position: 1.0; color: "green" }
}
border.color: "slategray"
}
Rectangle
Text {
text: "The quick brown fox"
color: "#303030"
font.family: "Century"
font.pixelSize: 28
}
elide elide
wrapMode
Text {
width: 160
height: 120
text: "A very very long text"
elide: Text.ElideMiddle
style: Text.Sunken
styleColor: '#FF4444'
verticalAlignment: Text.AlignTop
font {
pixelSize: 24
}
}
Text #FF4444
Sunken
Text
Image {
x: 12;
y: 12
// width: 48
// height: 118
source: "assets/rocket.png"
}
Image {
x: 112;
y: 12
width: 48
height: 118/2
source: "assets/rocket.png"
fillMode: Image.PreserveAspectCrop
clip: true
}
URL./images/home.png
http://example.org/home.png QML
Image.PreserveAspectCrop
clip
MouseArea
Rectangle {
id: rect1
x: 12;
y: 12
width: 76;
height: 96
color: "lightsteelblue"
MouseArea {
/* ~~ */
}
}
MouseArea QtQuick
40
79 QML
QML QML
QML
QML
Button.qml
QML Button { }
Rectangle
Rectangle {
id: root
Text {
id: label
anchors.centerIn: parent
text: "Start"
}
MouseArea {
anchors.fill: parent
onClicked: {
root.clicked()
}
}
}
main.qml
Rectangle {
width: 360
height: 360
Button {
id: button
x: 12; y: 12
text: "Start"
onClicked: {
status.text = "Button clicked!"
}
}
Text {
id: status
x: 12; y: 76
width: 116; height: 26
text: "waiting ..."
horizontalAlignment: Text.AlignHCenter
}
}
app
|- QML
| |- main.qml
|- components
|- Button.qml
Button Rectangle
Rectangle
Item Item