Qt学习笔记


前段时间连续学了一个半月的邵发Qt视频,学习的过程中做了笔记,以方便自己以后用的时候查看关键点。

将之放到网盘上,以供需要的朋友。

http://pan.baidu.com/s/1c2pwN8s

Chapter1 坐标的概念

每个窗体在屏幕的显示的位置是以左上角(top-left)的相对位置来定义的。左上角的坐标为(0,0),屏幕的长边为x轴,短边为y轴。

几乎每个窗体都有一个重构的函数setGeometry(x,y, length, width)。其中xy就是坐标系。注意此函数的的坐标的位置是不带边框的,只是现实窗体的位置。

move(x,y)函数则可以设定带边框的坐标。

Chapter2 定义自己的窗体

2.1Q_OBJECT

定义窗口类的时候一定要在头文件里面加上Q_OBJECT

2.2勿忘父窗口

创建子控件的时候要指定父窗口(QWidget*parent)。

3.3子控件的指针不需要手动delete

构造函数在new子窗口后,不用手动delete,由父窗口来管理。

3.4手动创建窗口的缺点

比较麻烦,不能自动调动窗口。


Chapter3 窗口布局layout

3.1QLayout布局器

其子类为QBoxLayout,又派生了QVBoxLayoutQHBoxLayout

3.2添加QLineEditQPlainTextEdit窗体

addWidgetobj;

3.3QPlainTextEdit随父窗口的变动而变动,体现了灵活性。

这是有Policy(策略)来决定的。

3.4设置布局器

Qwidget::setLayout(layout);来实现的


Chapter4 Policy窗口调整的策略

Fixed

使用sizeHint的大小,不能更大,也不能更小。

Preferred

优先使用sizeHint,可大可小。

Expanding

使用sizeHint,越大越好。

获取policy的方法

QSizePolicyQwidget::sizePolicy() const;

设置policy的方法

void QsizePolicy::setSizePolicy(QSizePolicy);

对于纵向布局,我们只关注其高度和纵向policy

Chapter5 手工布局

<span style="font-family:SimSun;">MyWin::MyWin(QWidget *parent)
	: QWidget(parent)
{
	m_lineEdit = new QLineEdit(this);
	m_textEdit = new QPlainTextEdit(this);
	m_button = new QPushButton(this);

	m_button->setText("Ok");
	QHBoxLayout *hLayout = new QHBoxLayout;
	hLayout->addWidget(m_lineEdit);
	hLayout->addWidget(m_button);

	QVBoxLayout *vLayout = new QVBoxLayout;
	vLayout->addLayout(hLayout);
	vLayout->addWidget(m_textEdit);

	this->setLayout(vLayout);
}</span>

局部变量hLayout,vLayout都叫父窗口管理(Qt)了,不用手动delete

Chapter6 可视化布局

QtDesigner工具来布局,最后一个控件不需要添加上去,只用点击布局就好。

Chapter7 stretch factor拉伸因子

Qt自动拉伸的时候,可以控制拉伸的因子。

在用QtDisigner的时候,文本框的右边选中属性框中的sizePolicy,设置HorizontalStretchVerticalStretch中的值。对于同一属性,如果是两个文本框,一个为1,一个为3,则在父框口变动的时候,这两个框口相应的边会按照比例来拉伸。

最大值最小值的设置。

minimumSizemaximumSize。注意和策略QSizePolicy::Maximum的区别,这是一个策略,以sizeHint为最大值,而minimumSizemaximumSize是一个属性,最大的范围。


Chapter8 Qt的事件处理

一个动作所对应的反应,就是事件处理。

SIGNALSLOTSLOT插槽的意思。

VS不能识别ui文件的解决,打开自动生成的ui的头文件,点击VAssistX--tools→ Reparse CurrentFile


Chapter9 QCheckBox

qDebug可以在debug模式下,打印调试信息。

signal

void stateChanged(int state);

DisplaywidgetsTextBrowser的用法,用于显示一堆文本数据。



Chapter10 QLineEdit

echoMode密码模式

echoMode输入模式– 如果是密码则选择password,这样在输入密码的时候,会以加密的形式显示。对应的是normal,这个则显示明码。

placeholderText:

行编辑空白处的提示字符。

文本内容的获取:

QString QlineEdit::text();

QMessageBox消息窗口:

当我们输入密码的时候,密码输入完毕后,点击确定,弹出密码正确或者错误的窗口。

头文件:QMessageBox,用法:QMessageBox::information(this,“title”, “message content”);


Chapter11Q ComboBox

如图:

手动创建

手动创建项目,QComboBox::addItem(“string”)insertItem(index,“string”);

以上index是下拉框从0开始上往下数的序号。

<span style="font-family:SimSun;">	ui.cmboxLang->addItem("Chi", "ch");
	ui.cmboxLang->addItem("Eng", "en");
	ui.cmboxLang->addItem("Fre", "fr");
	ui.cmboxLang->insertItem(2, "Kor", "ko");</span>

关联数据

QVariant &user。在addItem,insertItem的时候,最后一个参数是默认的,当显式传递参数的时候,则为组合框关联的数据。

如上代码示例中的ch,en,fr,ko

editable属性

QComboBox的第一个私有的属性就是editable,当选中它的时候,组合框里面是可以输入数据的,点击回车的时候,新添一个item

如图变为editable后的效果:


获取当前项的文本

QString value=ui.cmboxLang->currentText();

当手动输入其他字符的时候,当前项的文本会变成输入的字符。可是currentItem中的字符,还是之前没有输入字符时候的里面的默认值。


Chpater12 QToolButton

如图(没有设置图标和文本的样式):


icon最好选择png格式的,因为它是背景透明的。

加上icon以及文本后的效果:


toolButtonStyle(文本在icon下面



autoRaise(浮动)模式

私有属性autoRaise,表示浮动模式的意思。浮动模式的意思是当鼠标不在此控件上面的时候,没有外边框,当鼠标在控件上(选上的时候)显示外边框。如下图鼠标不在控件上:


signaltoggled

toggled信号只在checkablebutton按下去后才产生,参考“Thissignal is emitted whenever a checkable button changes its state.

Chapter13 QLabel

原生态的QLabel


设置背景色和前景色

右键点击QLabel后,选择“ChangeStyleSheet”color是前景色,backgroud-color是背景色。如下图:


换行模式(wordWrap

将此属性选上后,label一次显示不了那么多的文字,则自动换行,如下图:


label加外边框(QFrame--> frameShape --> Box


显示图片

收藏资源,ResourceBrowser --> EditResource -->选择已经下载好的图片,添加进去。

在属性pixmap上,选择收藏好的jpg图片。如果图片太大了,此时我们要缩放图片。

图片的缩放,使之自动适应label的大小scaleContents

选中scaleContents

Chapter14 字符集

Latin字符集


中文字符集

GB2312中文简体国标码(汉字数:6763),有局限性,有些生僻字不能显示。

GBK扩展中文GB编码(兼容GB2312)。更通用,因为范围广。

BIG5中文繁体字符集。

CJK中日韩大字符集。

Unicode统一码,映射全球各国的文字。

第一种方案:UTF-32。太浪费空间。

第二种方案:UTF-161~2short来表示。(unicode没有注明,则为UTF-16)

第三种方案:UTF-81~4个字节来表示一个字符。


字符集间的转换

每种字符集在特定的平台下都有系统API函数来相互转换的。如windows下,将GBK转化为unicodeUTF-16)的函数MultiByteToWideChar

Chapter15 QString

VC文件数据存储的格式

VC编辑器中代码的存储在中文windows下是以GBK的形式存在的。这句话的意味着,在qstring_st.cpp中如下的代码,里面的字符都是GBK的编码形式。其中英文部分是和unicode完全兼容的,但是汉字却不同。如下的“你好,中国!”,如果直接赋值给QString的对象str,会有问题。原因是QString类是以unicode的编码形式来输出的。

<span style="font-family:SimSun;">int QString_st::OnBtnTest()
{
	//QString str = "Hi, China!";
	QString str = "你好,中国!"; // 这样显示会出现乱码。
	ui.lineEdit->setText(str);

	return 0;
}</span>

GBK字符串转换成QString对象

QStringQString::fromLocal8Bit ( const char *str,intsize=-1 )[static]

如下实例:

QStringstr=QString::fromLocal8Bit("你好,中国!");


fromLocal8Bit的缺陷

windowsloacl8BitGBKlinuxlocal8BitUTF-8,所以上述转换的函数并不保险。考虑到跨平台的方面,需要其他的方法。

跨平台的处理方法

<span style="font-family:SimSun;">	QString test = ui.lineEdit->text();
	QByteArray bytes = test.toUtf8();
	const char *utf8 = bytes.data(); 
	int size = bytes.size();</span>

Chapter16 QDialog对话框

模式对话框

占用整个窗口,只能操作对话框里面的选项,其他地方不能操作的对话框。在生成QDialog对象后,默认的模式就是模式对话框。

非模式对话框

除了弹出的窗口可以设置以外,其他的界面亦可以操作的对话框。

新建对话框类的时候要选定父类是QDialog

对话框的生成(弹出)

执行函数intQDialog::exec ()后就会弹出对话框。

exec()执行后,程序会阻塞,直到调用accept()函数或者reject()函数。如下所示:

<span style="font-family:SimSun;">	#include <QDebug> // qDebug()需要的头文件。
	...

	LoginDlg *dlg = new LoginDlg(this);
	int ret = dlg->exec(); // 显示对话框,程序阻塞。直到accept()或者reject()函数调用。
	if (ret == QDialog::Accepted)
	{
		qDebug() << dlg->m_user << dlg->m_password;
		qDebug() << "accept()";
	}
	else if ( ret == QDialog::Rejected ) 
	{
		qDebug() << "reject()";
	}</span>

对话框标题栏的设置

先选中对话框对象,如下图所示:


然后在QWidget属性下设置windowTitle属性,如下图:


Chapter17 文件对话框

QFileDialog类实现文件对话框

一般最常用的是此类的静态函数QFileDialog::getOpenFileNameQFileDialog::getSaveFileName。当这两个函数被调用的时候会弹出相应的对话框,如下图打开对话框(保存对话框类似):


QFileDialog::getOpenFileName函数的使用

<span style="font-family:SimSun;">int QFileDialog_st::OnBtnOpen()
{
	QString filename = QFileDialog::getOpenFileName(this, GBK::ToUnicode("请选择一个文件"));

	if (filename.length() > 0) // 选择了要打开的文件
	{
		string gbkName = GBK::FromUnicode(filename);
		FILE *fp = fopen(gbkName.c_str(), "rb");

		fseek(fp, 0, SEEK_END);
		int filesize = ftell(fp);

		fseek(fp, 0, SEEK_SET);
		char *buf = new char[filesize + 1];
		//int n = fread(buf, filesize, 1, fp);
		int n = fread(buf, 1, filesize, fp);
		if (n > 0) 
		{
			buf[n] = 0;
			ui.plainTextEdit->setPlainText(GBK::ToUnicode(buf));
		}
		delete [] buf;
		fclose(fp);
	}

	return 0;
}</span>

QFileDialog::getSaveFileName函数的使用

<span style="font-family:SimSun;">int QFileDialog_st::OnBtnSave()
{
	QString filename = QFileDialog::getSaveFileName(this, GBK::ToUnicode("保存一下"));

	if (filename.length() > 0) // 选择了要保存的文件
	{
		string gbkName = GBK::FromUnicode(filename);
		FILE *fp = fopen(gbkName.c_str(), "wb");
		QString qstr = ui.plainTextEdit->toPlainText();
		string cstr = GBK::FromUnicode(qstr);
		fwrite(cstr.c_str(), 1, cstr.length(), fp);
		fclose(fp);
	}

	return 0;
}
</span>

Chapter18 定时器

定时器的使用分为两步走

1,重载虚函数void QObject::timerEvent (QTimerEvent*event)[virtualprotected]

重新定义timerEvent函数是作为时间超时后的总处理函数。如下:

<span style="font-family:SimSun;">#include <QTime> 
void TimerInQt::timerEvent(QTimerEvent *event)
{
	//qDebug() << event->timerId();
	if (event->timerId() == m_timerid) 
	{
		QTime now = Qtime::currentTime(); // 获取当前的时间
		QString text = now.toString("hh:mm:ss");
		qDebug() << text;
		ui.labelTime->setText(text);
	}
}</span>

2,创建并开始定时器。int QObject::startTimer ( int interval)

上述函数用于创建并开始定时器,其返回值就是创建的定时器的id,其参数是每隔多少毫秒触发一次timerEvent事件,事件触发后会调用timerEvent函数。

注意timerEvent函数不能够占用太久的时间,否则会阻塞其他事件的处理,如鼠标点击控件,退出界面,输入字符等等。

timerEvent并不是线程,它是界面处理线程轮询事件标记后的函数调用。

Chapter19 多线程

设计自己的线程

1,定义一个类,继承于QThread。如下:

<span style="font-family:SimSun;">#include <QThread>

class sendTask : public QThread
{
	Q_OBJECT

public:
	sendTask(QObject *parent);
	~sendTask();
	int getStatus();
	int getProcess();
	int beginTask(const char *filename);
	void DestroyThread(void);

private:
	// 线程的总入口函数。
	void run();

private:
	char m_filepath[128];
	int m_filesz;
	int m_bytesread;
	int m_status;
};</span>

2,重载线程入口函数:void run()

3,开启线程的函数:start()。继承自QThread,此函数可直接调用。

4,线程回收:wait()继承自QThread,此函数可直接调用。

补充知识 processBarQProcessBar

这个小控件可以显示进度条,如下所示:



Chapter20 容器

QTabWidget

原始模样的它:


用可视化布局的方式实现选项卡很简单。在QtDesigner里面点击Container->TabWidget->拖放到图形设计器里,设置下它的属性currentTabTextcurrentTabName。如下:


然后随意添加我们所需要的其他控件,我在第一个选项卡里面添加了一个lineEdit,第二个选项卡里添加了checkBox和一个pushButton。就成了如下的样子:


每个页面子控件的使用。在F7过后,上图ui会被自动生成相关代码。lineEditcheckBox以及pushButton,会被生成这个ui的成员变量,只要用ui.xxx就可以直接调用了,如下所示:

<span style="font-family:SimSun;">	QString str = ui.lineEdit->text();
	bool status = ui.checkBox->isChecked();</span>

QStackedWidget

原始模样的StackWidget


当生成一个原始模样的StackWidget的时候,我被它丑陋的外表所震惊了。什么都没有,只是在右上角的地方有两个黑色的小箭头。这个能干什么?

在其属性窗口里可以看到,它只有索引和名字,当可视化布局的时候,默认StackWidget有两页。右上角的箭头就是切换第0页和第1页的。

可见这个小控件提供的只是一个显示,两个页面重叠在一起,所以用stackwidget来命名。要想控制这两个页面,必须有两个按钮。在设计器里面添加两个按钮后,变成如下模样:


如上所说,这个默认的stackwidget有两个页面,显示哪个页面则需要专
用的函数,QStackedWidget::setCurrentIndex就是干这个事的。如下两个slot函数:

<span style="font-family:SimSun;">int QStackWidget_st::OnPage1()
{
	ui.stackedWidget->setCurrentIndex(0);

	return 0;
}

int QStackWidget_st::OnPage2()
{
	ui.stackedWidget->setCurrentIndex(1);

	return 0;
}</span>

Chapter21 QMainWindow

QMainWindow的外表

QMainWindow对象以及继承于它的对象,有一个显著的特点,那就是有菜单栏和工具栏。在qt助手里,我找到了QMainWindow对象的粗线条的描绘图,如下:


创建一个类继承于QMainWindow,得到一个原生态的界面如下(红色的注视是表明每个子窗体的名字):


添加QAction

一个QMainWindow没有action就什么都干不了。当在菜单栏里面添加一个action后,点击那个action就会做相应的动作。

1,下载相关的actionicon

推荐网站:http://www.easyicon.net/。在搜索栏里面输入save等,得到海量的icon,选择一个我们喜欢的风格,点击它。接着又有很多像素选择给我们选,一般都是选择24PX或者16PXpng格式的。将下载好的icon放入到项目的Resources目录下。

2,将下载好的icon添加进工程。

点击QtDesigner右下角的ResourceBrowser,进入EditResource对话框,然后单击如下圈中的图标:


3,添加QAction

点击右下角的ActionEdit,然后点击New工具,弹出Newaction对话框。


4,将编辑好的action放入菜单栏,或者工具栏里。

直接将编辑好的action左键单击选中后,拖到工具栏的TypeHere处,然后松掉鼠标。就添加成功了一个action,在代码里面用action的方法是直接ui.actionxxx,如上图的action,调用的方法是ui.actionHelp

添加action的事件处理函数(slot)

构造函数添加connect

<span style="font-family:SimSun;">	connect(ui.actionNew, SIGNAL(triggered ( bool ) ), this, SLOT(OnActionNew()));
	connect(ui.actionOpen, SIGNAL(triggered ( bool ) ), this, SLOT(OnActionOpen()));
	connect(ui.actionSave, SIGNAL(triggered ( bool ) ), this, SLOT(OnActionSave()));</span>

slot函数的实现

<span style="font-family:SimSun;">int QMainWindow_st::OnActionNew()
{
<span style="white-space:pre">	</span>// add your codes
	return 0;
}

int QMainWindow_st::OnActionOpen()
{
<pre name="code" class="html" style="color: rgb(1, 0, 1); font-size: 13.3333px;"><span>	</span>// add your codes</span>
return 0;}int QMainWindow_st::OnActionSave(){
<span style="font-family:SimSun;"><span>	</span>// add your codes</span>
return 0;}

Chapter22 自定义控件

1,绘制窗口

1.1添加类

添加类Qt4Class而非Qt4GuiClass,选择父类为QWidget或者QFrame。一般选择QFrame

1.2重载虚函数paintEvent,其原型为:

void QFrame::paintEvent (QPaintEvent*)[virtualprotected]

paintEvent是继承于QWidget类的一个虚函数,它是一个事件处理函数,当子类定义了后自动调用。在子类头文件里面声明:

<span style="font-family:SimSun;">class CircleWindow : public QFrame
{
	Q_OBJECT

public:
	CircleWindow(QWidget *parent);
	~CircleWindow();

private:
	void paintEvent(QPaintEvent *event);	// 声明paintEvent虚函数。
};
添加定义:
void CircleWindow::paintEvent(QPaintEvent *event)
{
	QPainter *painter = new QPainter(this);
	
	int w = this->width();
	int h = this->height();

	painter->setBrush(QBrush(QColor(0, 0xff, 0)));
	painter->drawEllipse(0, 0, w, h);
}</span>

1.3将自己定义的类CircleWindow作为控件添加到QtDesigner中。

1.3.1首先添加控件QFrame

1.3.2QFrame里面加入自己的控件(自己定义的QFrame类)

在添加的QFrame上右键单击,在弹出的框口上点击“PrototedWidgets...,弹出如下对话框



输入类名和头文件后,点击Add

将刚才添加的控件后面的选项框勾上。然后点击Promote


输入类名和头文件后,点击Add

将刚才添加的控件后面的选项框勾上。然后点击Promote




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值