《C++ GUI Qt 4 编程》 笔记(二)

第二部分 Qt中级

第6章 布局管理

分组布局
QStackedLayout 对一组子窗口部件进行摆放,或对它们进行分页。
QStackedWidget 内置QStackedLayout的QWidget

QTabWidget

切分窗口 QSplitter

滚动区域 QScrollArea
如果想给一个窗口部件添加一个滚动条,则可以使用一个QScrollArea类来实现。

停靠窗口
指一些可以停靠在QMainWindow中或者浮动为独立窗口的窗口。
Qt中,各个停靠窗口都是QDockWidget的实例。

如果需要一个浮动工具栏,只需把它放进QDockWidget

如果需要让停靠区重叠部分左上角属于左侧停靠区域:
QMainWindow::setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);

QMainWindow::saveState();
QMainWindow::saveGeometry();

多文档界面
Qt中,通过把QMdiArea类作为中央窗口部件,并且通过让每一个文档窗口都成为这个QMdiArea的子窗口部件,就可以创建一个多文档界面应用程序了。

第7章 事件处理

// 事件循环一空闲就会触发
QTimer::singleShot(0, this, SLOT(loadFiles));

QMdiSubWindow* subWindow = mdiArea->addSubWindow(editor);

代码编辑组件 QScintilla
www.riverbankcomputing.co.uk/qscintilla

定时器事件可以用来实现光标的闪烁和其他动画的播放,或只是简单地用作显示的刷新。

updateGeometry()通知对窗口部件负责的任意布局管理器,提示该窗口部件的大小发生了变化。

QWidget::scroll(-1, 0)把窗口部件的内容向左滚动一个像素

定时器事件是一种低级事件,如果需要多个定时器,保持并分鬃所有ID会很麻烦
更为简单的方式是,为每一个定时器分别创建一个QTimer对象。QTimer会在每个时间间隔发射timeout()信号。

Qt调用QApplication::notify()来发送一个事件。

对于耗时多的事件为了避免界面无法响应:
1. 多线程
2. 频繁调用QApplication::processEvents()
为避免在处理任务时关闭窗口或执行新任务:
qApp->processEvents(QEventLoop::ExcludeUserInputEvents); // 忽略键盘鼠标事件

QProcessDialog

0毫秒的定时器,只要没有其他尚待处理的事件,就可以触发这个定时器。

qApp->hasPendingEvents()

第8章 二维图形 QPainter

重写QWidget::paintEvent()可用于定制窗口部件,并且随心所欲地控制它们的外观。

QPen 画笔: 颜色 宽度 线型 拐点风格 连接风格
QBrush 画刷: 颜色 风格 纹理 渐变
QFont 字体: 字体族 磅值

drawPoint()
drawLine()
drawPolyline()
drawPoints()
drawLines()
drawPolygon()
drawRect()
drawRoundRect()
drawEllipse()
drawArc()
drawChord()
drawPie()
drawText()
drawPixmap()
drawPatch()

save() 将设备的当前状态存入一个内存堆栈
restore() 恢复设备状态

坐标系统
假设一个320×200的窗口部件

世界变换

painter.translate()
painter.rotate()

QDateTime::currentDateTime()

qBound(min, val, max)

QPainter实例 微波炉定时开关

QImage
在QWidget或QPixmap上绘图,需要依赖于平台自带的绘图引擎
画到一个QImage上,然后把结果复制到屏幕上。这样可以总是使用Qt自己内置的绘图引擎,在所有平台上得到同样的结果。

QGraphicsScene QGraphicsItem QGraphicsView
预定义的QGraphicsItem子类:
QGraphicsLineItem
QGraphicsRectItem
QGraphicsEllipseItem
QGraphicsPolygonItem
QGraphicsPathItem
QGraphicsPixmapItem
QGraphicsSvgItem
QGraphicsSimpleTextItem
QGraphicsTextItem

QGraphicsScene 有三层:
background layer
item layer
foreground layer
背景层和前景层由QBrush指定或重新实现drawBackground() drawForeground()

QGraphicsView 是一个窗口部件,这个窗口部件可以显示场景,在需要的情况下提供滚动条

class Node 中
Q_DECLARE_TR_FUNCTIONS(Node)
这种方法可以直接使用tr(),而不是静态的QObject::tr()或者QCoreApplication::translate()

当创建QGraphicsItem的子类时,要想自己实现绘图,一般是重新实现boundingRect()和paint()
如果不重新实现shape()基类的实现将会退而使用boundingRect()
视图体系用外接矩形来决定一个项是否需要被绘制
shape用来决定一个点是否在项内,或者是否两个项是重合的
shape用于精确的碰撞检查

update()安排一次重绘

计算包围文字的矩形

剪贴板
QApplication::clipboard()->setText(str);

QStyleOptionGraphicsItem::levelOfDetail
缩放因子
1.0 原始大小显示场景
0.5 以原始大小的一半显示场景
2.5 显示的大小是原始尺寸的2.5倍

缩放因子
QGraphicsView::scale()

在希望显示动画的项上使用QGraphicsItemAnimations
使用QTimeLine播放动画
也可以通过继承QObject(应用多继承)创建图形项的子类,重新实现QObject::timeEvent()显示动画

打印
1. 创建一个当作绘制设备的QPrinter
2. 弹出一个QPrintDialog对话框,以允许用户选择打印机并且设置一些选项
3. 创建一个在QPrinter上操作的QPainter
4. 调用QPainter::newPage()来进行下一页的绘制
5. 重复步骤4和步骤5,直到所有页都被打印为止

生成PDF文件
QPrinter::setOutputFormat(QPrinter::PdfFormat)

打印场景
QGraphicsScene::render()
QGraphicsView::render()

Qt::escape()把特殊字符 & < > 替换为相应的HTML项
&amp; &lt; & &gt;

第9章 拖放

QWidget::dragEnterEvent()
QWidget::dropEvent()
QWidget::setAcceptDrops(true);

// 推荐的拖动距离起始距离(通常是4个像素)
QApplication::startDragDistance()

开始一个拖动

响应dragEnter和dragMove代码相同

响应dragDrop

QMimeData成员函数支持纯文本、超文本、图像、URL、颜色

自定义拖动类型
方式1:
mimeData->setData(“text/csv”, toCsv(plainText).toUtf8());

Qt::escape() 转义HTML中的特殊字符

方式2:
继承自QMimeData
构造函数中:
// QStringList myFormats
myFormats << “text/csv” << “text/html”;

响应dragDrop时,强制转换为MyMimeData,如果成功,说明是同一个程序,获得MyMimeData中保存的Widget,直接读取数据。而不必经过QMimeData的应用程序接口。

MIME类型指定编码方式
text/plain;charset=UTF-8

剪贴板处理技术
QApplication::clipboard()返回QClipboard对象的指针
将数据放到剪贴板中
setText() setImage() setPixmap()
获取数据
text() image() pixmap()
自定义类型
setMimeData() mimeData()

如果想在剪贴板中的内容发生改变时就立即得到通报:
建立QClipboard::dataChanged()信号和自定义槽的连接即可。

《C++ GUI Qt 4 编程》 笔记(一)

第一部分 Qt基础

布局管理器
QHBoxLayout
QVBoxLayout
QGridLayout

1. 声明所需的窗口部件
2. 设置所应具备的属性
3. 添加到布局中
4. 连接信号和槽

对于定义了信号和槽的类,在类定义开始处的Q_OBJECT宏都是必需的。

当头文件中只使用了对象指针时,可以使用前置声明 比如class Fruit;

Qt模块
QtCore
QtGui
QtNetwork
QtOpenGL
QtScript
QtSql
QtSvg
QtXml

发射信号

一个信号可以有多个槽,
在发射信号时,会以不确定的顺序调用槽。
多个信号可以连接同一个槽。

信号可以与信号相连,发射第一个信号时,也会发射第二个信号。

移除连接
disconnect()

元对象系统
内省
即动态获得类有哪些函数、信号、槽、成员变量
如果信号的参数比槽的参数多,多余的参数被忽略。
这种机制可以应用于任何QObject的子类中

QIntValidator
QDoubleValidator
QRegExpValidator

动态加载ui文件

启动画面

子类化对话框
继承自QDialog
在构造函数中创建控件、布局

Q_OBJECT 信号和槽、内省
Q_OBJECT 定义了某些函数声明
moc工具生成函数定义

使用GUI设计工具
1. 创建并初始化子窗口部件
2. 把子窗口部件放到布局中
3. 设置Tab键顺序
4. 建立信号-槽之间的连接
5. 实现对话框中的自定义槽

uic工具会将.ui文件转换成c++

创建一个新类MyDialog从QDialog和Ui::MyDialog中继承,并且由它来实现那些缺失的功能。

通过简单地增加另外一个间接层就可以解决软件的任何问题。

setupUi()自动建立信号连接
槽命名规则 on_objectName_signalName() e.g. on_lineEdit_textChanged()

需要明确删除的对象是那些使用new创建的并且没有父对象的对象。

layout()->setSizeConstraint(QLayout::SetFixedSize);

内置窗口部件类和对话框类
QMenuBar
QToolBar
QStatusBar
QSplitter
QScrollArea
QPushButton QToolButton QCheckBox QRadioButton
QGroupBox QFrame
QTabWidget QToolBox
QAbstractScrollArea
QListView QTreeView QTableView
QLabel
QLCDNumber
QProgressBar
QTextBrowser
QLineEdit QTextEdit
QSpinBox QDoubleSpinBox QComboBox QDateEdit
QTimeEdit QDateTimeEdit QScrollBar QSlider QDial
QInputDialog
QProgressDialog
QMessageBox
QErrorMessage
QColorDialog
QFontDialog
QPageSetupDialog
QFileDialog
QPrintDialog
QFontComboBox
QWizard

closeEvent() 函数是QWidget类中的一个虚函数
当用户关闭窗口时,这个函数会被自动调用。

setCentralWidget()
中央窗口部件会占用主窗口的中央区域部分。

QWidget::setWindowIcon()

Qt资源机制
资源文件(xml) xxx.qrc

.pro 中 RESOURCES = xxx.qrc
所有资源文件都会编译到应用程序的可执行文件中。
引用资源 :/images/icon.png

动作 Action
一个动作就是一个可以添加到任意数量的菜单和工具栏上的项。

创建菜单和工具栏的步骤:
1. 创建并且设置动作
2. 创建菜单并且把动作添加到菜单上
3. 创建工具栏并且把动作添加到工具栏上

使用QActionGroup,可以实现互相排斥的复选动作

QApplication对象的aboutQt()槽

任何Qt窗口部件都可以有一个与之相关联的QActions列表。要为该应用程序提供一个上下文菜单,可以将所需要的动作添加到窗口部件中,并且将那个窗口部件的上下文菜单策略(context menu policy)设置为一个现实这些动作的上下文菜单。

一种更为高级的提供上下文菜单方法是重新实现QWidget::contextMenuEvent()函数,创建一个QMenu窗口部件,在其中添加所期望的那些动作,并且再对该窗口部件调用exec()函数。

QMessageBox::warning(parent, title, message, buttons);
QMessageBox::information()

QFileDialog::getOpenFileName()
QFileDialog::getSaveFileName()

QMessageBox::question()
QMessageBox::critical()

当最后一个窗口关闭后,应用程序就结束了。
通过把QApplication的quitOnLastWindowClosed属性设置为false,应用程序将会持续保持运行,直到调用QApplication::quit()函数,程序才会结束。

QFileInfo(fullFileName).fileName();

每个QWidget都有一个windowModified属性,如果该窗口的文档存在没有保存的变化,则应当把它设置为true,否则应当设为false。window未保存的文件名后跟一个星号,mac使用另外的方式,Qt会自动处理。只需让windowModified属性保持当前最新状态,并且当需要显示星号的时候将”[*]”放在窗口的标题栏上即可。

每个动作(action)都可以带一个与之相关的QVariant,setData()

在槽中,使用QObject::sender()查出是哪个特有动作调用了这个槽。

qobject_cast<T>() 与 dynamic_cast<T>()不同的是,可正确地跨越动态库边界。

非模态对话框
show() 显示
raise() 称为顶层窗口
activateWindow() 激活状态

模态对话框
show() setModal()
-or-
// exec()返回值
// true QDialog::Accepted
// false QDialog::Rejected
exec()

QSettings类
windows 注册表
unix 文本文件
mac os x Core Foundation Preferences的应用程序编程接口

值的类型:int bool double QSetting QStringList QVariant

获得值

QApplication::closeAllWindows()会关闭所有应用程序的窗口。

启动画面的作用
1. 对缓慢的启动过程进行掩饰
2. 满足市场部门的要求

通过对一个已经存在的Qt窗口部件进行子类化或者
直接对QWidget进行子类化,就可以创建自定义窗口部件

整数转为16进制

子类化QWidget

QWidget::updateGeometry()
告诉包含这个窗口部件的任意布局,这个窗口部件的大小提示已经发生改变了,于是,该布局将会自动适应这个新的大小提示

强制产生一个绘制事件
QWidget::update() 在Qt下一次处理事件时才简单地调用一个绘制事件
QWidget::repaint() 即时的重绘事件

每一个窗口部件都会配备一个调色板,由它来确定做什么事应该使用什么颜色

Qt::WA_StaticContents属性
当重新改变窗口部件的大小时,这个窗口部件的内容并没有发生变化,而且它的内容仍然保留从窗口部件左上角开始的特性。当重新定义窗口部件的大小时,通过使用这个信息,Qt就可以避免对已经显示区域的重新绘制。

第三方窗口部件
GraphPak
KD Chart
Qwt

QApplication::setOverrideCursor()
QApplication::restoreOverrideCursor()

OGRE 笔记 材质脚本

http://www.ogre3d.org/docs/manual/manual_14.html#Material-Scripts