一直被超越,从未被模仿

Craft Life, Don't let life Craft you.

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

博客搬家自 http://zhouyuanchao.com/wordpress/archives/62


第一部分 Qt基础

#include <QApplication>
#include <QLabel>
int main(int argc, char* argv[])
{
	QApplication app(argc, argv);
	QLabel* label = new QLabel("Hello Qt!");
	label->show();
	return app.exec();
}
// 信号和槽
#include <QApplication>
#include <QPushButton>
int main(int argc, char* argv[])
{
	QApplication app(argc, argv);
	QPushButton* button = new QPushButton("Quit");
	QObject::connect(button, SIGNAL(clicked()),
		&app, SLOT(quit()));
	button.show();
	return app.exec();
}

布局管理器
QHBoxLayout
QVBoxLayout
QGridLayout

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

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

class FindDialog : public QDialog
{
	Q_OBJECT
public:
	FindDialog(QWidget* parent = 0);

	// signals关键字实际上是一个宏
signals:
	void findNext(const QString& str, Qt::CaseSensitivity cs);
	// ...

private slots:
	void findClicked();
	// ...
}

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

Qt模块
QtCore
QtGui
QtNetwork
QtOpenGL
QtScript
QtSql
QtSvg
QtXml

tr("Match") // 多语言支持

label->setBuddy(lineEdit); // 按下标签的快捷键时,焦点会移到lineEdit
button->setDefault(true); // 默认按钮
rightLayout->addStretch(); // 伸展器
dialog->setFixedHeight(sizeHint())
sizeHint() 返回窗口部件的理想尺寸大小

发射信号

emit findPrevious(text, cs);

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

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

移除连接
disconnect()

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

QIntValidator
QDoubleValidator
QRegExpValidator

动态加载ui文件

QUiLoader uiLoader; // CONFIG += uitools
QFile file("sortdialog.ui");
QWidget* sortDialog = uiLoader.load(&file);
QComboBox* primaryColumnCombo = 
sortDialog->findChild<QComboBox*>("primaryColumnCombo");

启动画面

QSplashScreen
QSplashScreen* splash = new QSplashScreen;
splash->setPixmap(QPixmap(":/images/splash.png"));
splash->show();
// ... load something
splash->showMessage(...);
mainWindow.show();
splash->finish(&mainWindow);
delete splash;

子类化对话框
继承自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

<RCC>
	<qresource>
		<file>images/icon.png</file>
		...
	</qresource>
</RCC>

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

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

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

newAction = new QAction(tr("&New"), this);
newAction->setIcon(QIcon(":/images/new.png"));
newAction->setShortcut(QKeySequence::New); // exitAction->setShortcut(tr("Ctrl+Q"));
newAction->setStatusTip(tr("Create a new spreadsheet file"));
connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));
// 复选动作
newAction->setCheckable(true);
newAction->setChecked(true);

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

QApplication对象的aboutQt()槽

// QMainWindow::menuBar()返回一个指向QMenuBar的指针,
// 菜单栏会在第一次调用menuBar()函数的时候就创建出来。
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAction);
fileMenu->addAction(openAction);
separatorAction = fileMenu->addSeparator();

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

spreadsheet->addAction(cutAction);
spreadSheet->addAction(copyAction);
spreadSheet->addAction(pasteAction);
spreadSheet->setContextMenuPolicy(Qt::ActionsContextMenu);

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

// 工具栏
fileToolBar = addToolBar(tr("&File"));
fileToolBar->addAction(newAction);
editToolBar = addToolBar(tr("&Edit"));
editToolBar->addAction(cutAction);
editToolBar->addSeparator();
// 状态栏
locationLabel = new QLabel(" W999 ");
locationLabel->setAlignment(Qt::AlignHCenter);
locationLabel->setMinimumSize(locationLabel->sizeHint());
formulaLabel = new QLabel;
formulaLabel->setIndent(3);
statusBar()->addWidget(locationLabel);
statusBar()->addWidget(formulaLabel, 1); // 第二个参数 窗口大小改变时是否伸展

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

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

// 状态栏显示一个2秒的信息
statusBar()->showMessage(tr("File loaded"), 2000);

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

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

QFileInfo(fullFileName).fileName();

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

// 使用参数替换%n
tr("%1[*] - %2").arg(shownName).arg(tr("Spreadsheet"))
showName + tr("[*] - Spreadsheet");

// QStringList recentFiles
QMutableStringListIterator i(recentFiles);
while (i.hasNext)
{
	if (!QFile::exits(i.next()))
	i.remove();
}

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

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

QAction* action = qobject_cast<QAction*>(sender());
if (action)
	// ...

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

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

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

QString str;
str.mid(1).toInt();
str[0].unicode() - 'A';
QMessageBox::about(this, tr("About Spreadsheet"),
	tr("<h2>Spreadsheet 1.1</h2>"
	   "<p>Copyright &copy; 2008 Software Inc.</p>"));

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

QSettings settings("组织名字", "应用程序名字");
settings.setValue("geometry", ...);
settings.setValue("findDialog/matchCase", ...);
settings.beginGroup("findDialog");
settings.setValue("matchCase", ...);
settings.endGroup();

值的类型:int bool double QSetting QStringList QVariant

获得值

settings.value("geometry").toByteArray();
settings.value("showGrid", true).toBool(); // 第二个参数:默认值

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

// 默认关闭窗口只是隐藏窗口
// 以下代码会使Qt在关闭窗口时将其删除
QWidget::setAttribute(Qt::WA_DeleteOnClose);
// 遍历所有主窗口
foreach (QWidget* win, QApplication::topLevelWidgets())
{
	MainWindow* mainWin = qobject_cast<MainWindow*>(win);
}

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

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

整数转为16进制

QString::number(value, 16).toUpper();
text.toInt(&ok, 16);

子类化QWidget

class IconEditor : public QWidget
{
	Q_OBJECT
	// 这些属性将显示在Qt设计师中
	Q_PROPERTY(QColor penColor READ penColor WRITE setPenColor)
};
QRgb red = qRgb(255, 0, 0);

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

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

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

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

第三方窗口部件
GraphPak
KD Chart
Qwt

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


阅读更多
文章标签: Qt 笔记
个人分类: 笔记 Qt
想对作者说点什么? 我来说一句

C++ GUI QT 4编程(第二版).pdf

2013年09月29日 21.13MB 下载

C++ GUI Qt 4编程(第二版)源码

2017年09月24日 3.07MB 下载

C++ GUI Qt 4 编程(第二版)》PDF

2011年03月10日 14.65MB 下载

没有更多推荐了,返回首页

不良信息举报

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

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭