Qt入门
QT_for_linux
第一个QT应用程序
-
重点掌握开发流程
(1)创建工程目录
mkdir Hello #每个QT程序都要放在一个独立的工程目录下
(2)进入工程目录编写源代码
vi main.cpp #语法和C++保持基本一致,但使用QT的类库不再是标准C++的库
int main(int argc,char** argv)
{
//创建QT应用程序对象
QApplication app(argc,argv);
//创建标签控件
QLabel label("Hello Qt!");
//显示标签控件
label.show();
//让应用程序进入事件
return app.exec();
}(3)构建工程
qmake -prohect #生成工程文件Hello.pro,并在文件中添加构建选项,QT += widgets
(4)创建Makefile
qmake #可以根据上一步的工程文件自动生成Makefile
(5)编译连接
make #执行即可完成编译与链接
(6)测试
./Hello #运行,默认名字与工程名字一致
QT中文编码
-
QT内部使用unicode编码,通常是UTF-16
-
QT的优化UTF-8转换为UTF-16
-
通过QTextCodec编码转换
QTextCodec *coder = QTextCodec::codeForName("GBK");
QString string = codec->toUnicode("GBK编码的中文字符串");
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec *coder = QTextCodec::codecForName("GBK");
QLabel label(coder->toUnicode("我是标签"));
label.show();
QPushButton button(coder->toUnicode("我是按钮"));
button.show();
return a.exec();
}
父窗口
-
创建控件时,可以指定停靠再某个父窗口上面,这时控件将作为子窗口
-
Qwidget及其子类的对象可以作为其它控件的父窗口
-
常用的父窗口类又如下三个:
-
QWidget
-
QMainWindow(主窗口) //QWidget的直接子类
-
QDialog(对话框) //QWidget的直接子类
-
父窗口的析构函数回自动销毁其所有的子窗口对象,因此即使子窗口对象时通过new操作符动态创建的,可以不显示的执行delete,而且不用担心内存泄漏问题,只要保证父窗口对象被正确销毁,其子窗口也将随之被销毁。
-
设置窗口的位置和大小
void move(int x,int y);
void resize(int w,int h);
例子
|
信号和槽
-
信号和槽是QT自行定义的一种通信机制,实现对象之间的数据交互。
-
当用户或系统触发了一个动作,导致某个控件的状态发生了改变,该控件就会发射一个信号,即调用其类中一个特定的成员函数(信号),同时还有可能携带有必要的参数。
-
槽和普通的成员函数几乎没有太多区别,可以是公有的、保护的或私有的,可以被重载,也可以被覆盖,其参数可以是任意类型,并可以像普通成员函数一样调用
-
槽函数与普通成员函数的差别并不在于其语法特性,而在于其功能。槽函数更多体现为对某种特定信号的处理,可以将槽和其他对象信号建立连接,这样当发射信号时,槽函数将被触发和执行,进而来完成具体功能。
-
型号函数
class XX:public QObject{
Q_OBJECT//宏,moc
signals:
void signal_func(..); //信号函数
};
//信号函数只需声明,不能写定义 -
槽函数
class XX:public QObject{
Q_OBJECT//moc原对象编译器
public slots:
void slot_func(..){..}//槽函数
};
//槽函数可以连接到某个信号上,当信号被发射时,槽函数将被触发和执行,另外槽函数也可以当作普通的成员函数直接调用。 -
信号和槽的连接
QObject::connect(const QOject *sender,const char * signal,const QObject * receiver,const char * method);
//参数
sender:信号发送对象指针
signal:要发送的信号函数,可以使用"SIGNAL(..)"宏进行类型转换
receiver:信号的接收对象指针
method:接收信号要执行的槽函数,可以使用"SLOT(..)"宏进行类型转换
案例
创建Qt应用程序,包含标签和按钮两个控件,实现点击按钮关闭标签
- 按钮点击时发送信号:clicked()
- 实现标签关闭功能的槽:close()
|
信号和槽连接的语法要求
-
信号和槽参数要一致
QObject::connect(A,SIGNAL(sigfun(int)),B,SLOT(slotfun(int))); //OK
QObject::connect(A,SIGNAL(sigfun(int)),B,SLOT(slotfun(int,int))); //error -
可以带有缺省参数
QObject::connect(A,SIGNAL(sigfun(int)),B,SLOT(slotfun(int,int=0))); //OK
-
信号函数的参数可以多于槽函数
QObject::connect(A,SIGNAL(sigfun(int,int)),B,SLOT(slotfun(int)))); //OK
-
一个信号可以被连接到多个槽
QObject::connect(A,SIGNAL(sigfun(int)),B1,SLOT(slotfun(int)))); //OK
QObject::connect(A,SIGNAL(sigfun(int)),B2,SLOT(slotfun(int)))); //OK
//触发的顺序不确定 -
多个信号也可以连接到同一个槽
QObject::connect(A1,SIGNAL(sigfun1(int)),B,SLOT(slotfun(int)))); //OK
QObject::connect(A2,SIGNAL(sigfun2(int)),B,SLOT(slotfun(int)))); //OK -
两个信号可以直接连接(信号级联)
QObject::connect(A1,SIGNAL(sigfun2(int)),A2,SLOT(sigfun2(int)))); //OK
-
案例
创建QT应用程序,包含滑块(QSlider)和选值框(QSpinBox),通过信号和槽的机制,保持同步运行
int main(int argc,char **argv)
{
QApplication app(argc,argv);
QDialog parent;
parent.resize(320,240);
//创建水平滑块
QSlider slider(Qt::Horizontal,&parent);
slider.move(20,100);
slider.setRange(0,200);
//创建选值框
QSpinBox spin(&parent);
spin.move(220,100);
spin.setRange(0,200);
//滑块滑动,选值框随之改变
QObject ::connect(&slider,SIGNAL(valueChanged(int)),&spin,SLOT(setValue(int)));
//改变选值,滑块改变
QObject ::connect(&spin,SIGNAL(valueChanged(int)),&slider,SLOT(setValue(int)));
parent.show();
return app.exec();
}
面向对象的Qt编程
-
基于对象的Qt编程,有限制
-
通过面向对象的编程思想实现加法计算器
-
案例
计算器实现
calcuator.h
class Calculator : public QDialog
{
Q_OBJECT //mocQt语法扩展
private:
QLineEdit* m_editX;
QLineEdit* m_editY;
QLineEdit* m_editZ;
QLabel* m_label;
QPushButton* m_button;
public:
Calculator(void);
~Calculator();
public slots:
//使能的能耗按钮的槽操作数
void enableButton(void);
void calcClicked(void);
};calculator.cpp
Calculator::Calculator(void)
{
//界面初始化
setWindowTitle("计算器");
//左操作数,this即为当前父窗口指针
m_editX = new QLineEdit(this);
//设置文本对齐:右对齐
m_editX->setAlignment(Qt::AlignRight);
//设置数字验证器,只能输入数字形式内容
m_editX->setValidator(new QDoubleValidator(this));
//右操作数
m_editY = new QLineEdit(this);
//设置文本对齐:右对齐
m_editY->setAlignment(Qt::AlignRight);
//设置数字验证器,只能输入数字形式内容
m_editY->setValidator(new QDoubleValidator(this));
//显示结果
m_editZ = new QLineEdit(this);
m_editZ->setAlignment(Qt::AlignRight);
m_editZ->setReadOnly(true);//设置为只读
//"+"
m_label = new QLabel("+",this);
//"="
m_button = new QPushButton("=",this);
m_button->setEnabled(false); //设置禁用
//创建布局器:自动调整每个控件的大小和位置
QHBoxLayout* layout = new QHBoxLayout(this);
//按水平方向,依次添加控件到布局器中
layout->addWidget(m_editX);
layout->addWidget(m_label);
layout->addWidget(m_editY);
layout->addWidget(m_button);
layout->addWidget(m_editZ);
//设置布局器
setLayout(layout);
//信号和槽函数连接
//左右操作数文本改变时,发送信号textChanged()
connect(m_editX,SIGNAL(textChanged(QString)),this,SLOT(enableButton(void)));
connect(m_editY,SIGNAL(textChanged(QString)),this,SLOT(enableButton(void)));
//点击按钮,发送信号clicked
connect(m_button,SIGNAL(clicked(void)),this,SLOT(calcClicked(void)));
}
Calculator::~Calculator()
{
}
void Calculator::enableButton(void){
bool bX0k = 0,bY0k = 0;
//text:获取输入文本(QString)
//toDouble():QString转换为double,参数保存转换是否成功结果
m_editX->text().toDouble(&bX0k);
m_editY->text().toDouble(&bY0k);
//左右操作数都为有效数字,则使能等号按钮,否则设置禁用
m_button->setEnabled(bX0k && bY0k);
}
//计算结果和显示的槽函数
void Calculator::calcClicked(void){
double res = m_editX->text().toDouble()+m_editY->text().toDouble();
//number():将double转换为QString
QString str = QString::number(res);
//显示字符串形式结果
m_editZ->setText(str);
}mian.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Calculator w;
w.show();
return a.exec();
}
参考文献
。。