QT
快捷键
注释 ctrl + /
运行 ctrl + r
编译 ctrl + b
查找 ctrl + f
整行移动 ctrl + shift + 上/下
自动对齐 ctrl + i
帮助文档 F1
同名间的 .h 和 .cpp 切换 F4
自动补全 ctrl+space
常用头文件
#include <QPushButton> 按钮
#include <QDebug> debug输出
#include <QWidget> 空窗口
#include <QMainWindow> 带部件的窗口
#include <QStatusBar> 状态栏
#include <QLabel> 标签控件
#include <QDockWidget> 铆接部件(浮动窗口)
#include <QTextEdit> 设置中心部件 (记事本)
#include <QMenuBar> 菜单
#include <QToolBar> 工具栏
创建一个桌面应用程序,有三种类
QWidget QMainWindow QDialog
其中 QWidget是父类,表示一个空窗口, QMainWindow是一个窗口,包含状态栏菜单栏等信息,QDialog 表示对话框
qt对象树
方便内存管理
当父对象析构的时候,这个子对象列表中的所有对象都会被析构,当析构子对象的时候,会自动从父对象的子对象列表中删除。
在窗口中new很多控件,可以没有delete,因为在父控件销毁时这些子控件以及布局管理器对象会一并销毁。
当创建的对象在堆区时候,如果指定的父亲是QObject派生下来的类或者QObject子类派生下来的类,可以不用管理释放操作,会将对象放入对象树中,自动释放掉,一定程度上简化了内存回收机制,
信号与槽
连接函数:connect( 信号的发送者,发送的具体信号,信号的接收者,信号的处理)
信号槽的优点:松散耦合 ,信号发送端和接收端本身没有关联,通过connect松散耦合连接在一起
实现 点击按钮关闭窗口:
参数1:信号的发送者,参数2:发送的信号(函数的地址)参数3:信号的接受者 参数4:处理的槽函数(函数地址)
connect(mybut,&QPushButton::clicked,this,&myWidget::close);
自定义信号和槽
自定义信号 返回值void 只需要声明,不需要实现 可以有参数,写到signals下面
自定义槽 返回值void 需要声明,需要实现 可以有参数,也可以重载,写到public slot下
触发自定义的信号 emit
connect(zt,&Teacher::hunger,st,&Student::treat);
//调用信号
classIsOver();
}
void Widget::classIsOver()
{
//调用信号
emit zt->hunger();
}
当自定义信号和槽出现重载
使用函数指针,明确指向函数的地址
带参数的槽函数,出现重载,在连接信号时通过函数指针告诉编译器是有参的还是无参的
//使用函数指针指向重载的函数
void (Teacher:: *teachersingnal)(QString)=&Teacher::hunger;
void (Student:: *stundets)(QString)=&Student::treat;
connect(zt,teachersingnal,st,stundets);
classIsOver();
}
用QSting定义的变量使用qDebug输出打印有""会自动加上双引号 ,先用 .ToUtf8()转为 QByteArray,再用 .Data转为char*
void Student::treat(QString food){
//Qstring->char * ,先转换成QByterray (.toUtf8() ),再转成char * (.data() )
qDebug()<<"吃"<<food.toUtf8().data();
}
信号连接信号
void (Teacher:: *teachersingnal)(void)=&Teacher::hunger;
void (Student:: *stundetstlos)(void)=&Student::treat;
//老师信号 连接到学生请客的槽
connect(zt,teachersingnal,st,stundetstlos);
//点击信号,连接到老师信号
connect(btn,&QPushButton::clicked,zt,teachersingnal);
//断开信号(参数里面为要断开的信号)
disconnect(btn,&QPushButton::clicked,zt,teachersingnal);
扩展:
1:信号可以连接信号
2:一个信号连接多个信号
3:多个信号可以连接同一个槽函数
4:信号和槽的的参数,类型必须一一匹配
5:信号的槽的参数个数,信号的参数个数可以多与槽参数的个数
QT4版本连接信号与槽
connect(zt,SIGNAL(hunger()),st,SLOT(treat()));
connect(zt,SIGNAL(hunger(QString)),st,SLOT(treat(QString)));
优点,参数直观 缺点:类型不做检测,参数不一致,也能通过,在运行阶段才报错
QT5以上支持QT4写法。
Lambda表达式
格式
[capture ] (parameters)mutable->return-type{statement}
[=]()->int{
btn->setText("rx");
return 666;
}();
[] 表示符,表示一个匿名函数
-
= 值传递
-
& 引用传递
() 参数列表
{} 函数主体实现
mutable 修饰符传递变量,表示可以修改拷贝的数据,但无法修改变量主体。(默认变量为只读,不可修改)
返回值 [] ()->int{}
作用:可以直接在lambda表达式中定义多个需要的操作
QMainWindow
菜单栏,最多一个
//创建菜单栏
QMenuBar *bar =menuBar();
//将bar放入窗口中
setMenuBar(bar);
//创建菜单
QMenu *fileMenu= bar->addMenu("文件");//返回值类型Qmenu
//创建菜单项
QAction *newaction=fileMenu->addAction("新建");
QAction *open= fileMenu->addAction("打开");
//添加分割符
fileMenu->addSeparator();
fileMenu->addAction("保存");
工具栏,可以有多个
QToolBar *toolbar=new QToolBar(this);
addToolBar(Qt::LeftToolBarArea,toolbar);//使用参数设置默认左边
//设置只允许左右停靠
toolbar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea);
//设置浮动
toolbar->setFloatable(false);//参数bool值
//设置移动
toolbar->setMovable(true);//参数bool值
//工具栏设置内容
toolbar->addAction(newaction);//此按键和菜单栏功用一个新建 newaction为菜单栏的菜单项
toolbar->addSeparator();//分割线
toolbar->addAction("打开");
//工具栏添加控件
QPushButton *btn=new QPushButton("打印",this);
toolbar->addWidget(btn);
状态栏 只能一个
QStatusBar *stbar=statusBar();
//设置到窗口
setStatusBar(stbar);
//放标签控件
QLabel *lab=new QLabel("问题1",this);
QLabel *lab2=new QLabel("问题2",this);
stbar->addWidget(lab);//默认在左边
stbar->addPermanentWidget(lab2);//显示在右边
铆接部件(浮动窗口) 可以多个
QDockWidget *dockWidget=new QDockWidget("浮动",this);
addDockWidget(Qt::TopDockWidgetArea,dockWidget);//其位置相对于中心部件
//设置后期停靠区域,只允许上下
dockWidget->setAllowedAreas(Qt::TopDockWidgetArea|Qt::BottomDockWidgetArea);
设置中心部件 中心部件只能有一个
QTextEdit *edit=new QTextEdit(this);// (设置一个记事本)
setCentralWidget(edit);
资源文件的添加
1:将资源文件拷贝到项目位置下
2:创建一个新文件->右键项目->添加新文件->Qt->Qt resouece File ->给资源文件起名,
3:资源名字为res ,添加后缀qrc,为res.qrc
4:open in editor打开 编译资源
5:先添加前缀,在添加资源
6:使用,“:+ 前缀名+文件名称”
ui->actionopen->setIcon(QIcon(":/icon1/image/open.jpg"));
ui->actionnew->setIcon(QIcon(":/icon1/image/new.jpg"));
对话框
头文件 #include <QDialog>
对话框分类:
-
模态对话框(不可以对其他窗口 进行操作)
-
非模态对话框(创建后可以也对其他窗口进行操作)
//模态对话框创建
QDialog dlg(this);
dlg.resize(200,100);//设置对话框大小
dlg.exec();//表示模态对话框 阻塞
//非模态对话框创建
QDialog *dlg2=new QDialog(this);//防止一闪而过,使用new创建,创建于堆区
dlg2->setAttribute(Qt::WA_DeleteOnClose);//在点击关闭对话框后释放掉资源
dlg2->resize(200,100);
dlg2->show();
消息对话框
QMessageBox类
#include <QMessageBox>
//错误对话框
QMessageBox::critical(this,"critical","错误");//参数1 父类 2 标题 3 提示
//信息对话框
QMessageBox::information(this,"info","信息");
//提问对话框 返回值StandardBotton,利用返回值判断用户的选择
if ( QMessageBox::Save==QMessageBox::question(this,"ques","提问",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel)){
qDebug()<<"保存";
}//参数4 关联按键类型,参数5 默认关联回车
else{
qDebug()<<"取消";
}
//警告对话框
QMessageBox::warning(this,"waring","警告");
其他对话框
颜色对话框
#include <QColorDialog>
QColor color=QColorDialog::getColor(QColor(155,0,0));
qDebug()<<"r="<<color.red()<<"g="<<color.green()<<"b="<<color.blue();
文件对话框
#include <QFileDialog>
参数1 父亲 参数2 标题 参数3 打开路径 参数4 过滤文件格式
QString str= QFileDialog::getOpenFileName(this,"打开文件","/etc","(*.txt)");//返回值为路径
字体对话框
#include <QFontDialog>
bool flag;
QFont font=QFontDialog::getFont(&flag,QFont("宋体",32));
qDebug()<<"字体"<<font.family()<<"加粗?"<<font.bold()<<"倾斜?"<<font.italic();
界面布局
实现一个登录的窗口
利用布局的方式 给窗口进行美化
选取一个Widget进行布局 水平布局 垂直布局 栅格布局
给用户名,密码,登录,退出的按钮进行布局
默认窗口和控件间有9间隙,可以调整 layoutLeftMargin
利用弹簧进行布局
控件
按钮组
QPushButton 常用按钮
QToolButton 工具按钮,用于显示图片,如图想显示文字,修改风格:toolButtonStyle, 凸起风格 autoRaise
radioButton 单选按钮,设置默认 ui->radioButton_1->setChecked(true);
checkBox 多选按钮,监听状态,2是选择,1是半选,0是未选中
QListWidget列表容器
QListWidgetItem* item 一行内容
ui->listWidget->addItem(item);
设置居中方式 item->setTextAlignment(Qt::AlignHCenter);
利用addItems 一次性添加整个内容
//利用listidget 写诗
QListWidgetItem* item=new QListWidgetItem("吾爱有三 \n日月与你 \n白天的太阳 \n晚上的月亮 \n还有永远的你");
ui->listWidget->addItem(item);
item->setTextAlignment(Qt::AlignHCenter);
//使用qt风格的字符串列表
QStringList list;
list<<"吾爱有三"<<"日月与你"<<"白天的太阳"<<"晚上的月亮"<<"还有永远的你";
ui->listWidget->addItems(list);
QTreeWidget树控件
设置头
ui->treeWidget->setHeaderLabels(QStringList()<<“英雄”<<“英雄简介”);//匿名对象
创建根节点
QTreeWidgetItem *witem=new QTreeWidgetItem(QStringList()<<“物理”);
添加根节点到树控件
ui->treeWidget->addTopLevelItem(witem);
添加子节点
QStringList hero1;
hero1<<“影流之主”<<“暗影刺客,杀人于无形”;
QTreeWidgetItem * Hero1=new QTreeWidgetItem(hero1);
witem->addChild(Hero1);
QTableWigdet表格控件
//设置列数
ui->tableWidget->setColumnCount(3);
ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"姓名"<<"性别"<<"年龄");
//设置行数
ui->tableWidget->setRowCount(5);
//设置正文
ui->tableWidget->setItem(0,0,new QTableWidgetItem("设置0,0位置"));
QStringList namelist;
namelist<<"张飞"<<"关羽"<<"马超"<<"赵云"<<"黄忠";
QList<QString>sexlist;
sexlist<<"男"<<"男"<<"男"<<"男"<<"男";
for(int i=0;i<5;i++){
int col=0;
ui->tableWidget->setItem(i,col++,new QTableWidgetItem(namelist[i]));
ui->tableWidget->setItem(i,col++,new QTableWidgetItem(sexlist.at(i)));
ui->tableWidget->setItem(i,col++,new QTableWidgetItem(QString::number(i+20)));
}
其他控件
stackWidget 栈控件
ui->stackedWidget->setCurrentIndex(0);
下拉框
ui->comboBox->addItem(“上校”);
Qlable显示图片
ui->lbl_image->setPixmap(Qpixmap("":/image/filename.png"));
Qlable显示动图
Qmovie * movie=new QMovie(":/image/mlg.gif")
ui->lib_movie->setMovie(movie);
movie->start();
自定义控件
添加新文件 Qt->设计师界面类( .h .cpp .ui)
.ui中设计了QSpinBox和Slider两个控件
Widget中使用封装的控件:
- Widget中拖拽一个Widget,点击提升为,点击添加,点击提升
实现功能,改变数字,滑动条跟着移动,信号槽监听
提供get和set对外接口 测试接口
//QspinBox移动,Qslider跟着移动
void (QSpinBox:: *spSignal)(int)=&QSpinBox::valueChanged;//函数指针
connect(ui->spinBox,spSignal,ui->horizontalSlider,&QSlider::setValue);
//Qslider移动,QspinBox跟着改变
connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);
//get(),set()为自己封装
//获取当前值
connect(ui->btn_get,&QPushButton::clicked,[=](){
qDebug()<< ui->widget->get();
});
//设置到一半
connect(ui->btn_set,&QPushButton::clicked,[=](){
ui->widget->set(50);
});
Qt中事件
鼠标事件
鼠标进入事件
void myLable::enterEvent(QEvent *event){
qDebug()<<"鼠标进入";
}
鼠标离开事件
void myLable::leaveEvent(QEvent *){
qDebug()<<"鼠标离开";
}
鼠标按下事件
void myLable::mousePressEvent(QMouseEvent *ev){
//鼠标左键按下
if(ev->button()== Qt::LeftButton){
QString str=QString("x=%1 y=%2 globalx=%3 globaly=%4" ).arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<"鼠标按下"<<str;
}
}
鼠标释放事件
void myLable::mouseReleaseEvent(QMouseEvent *ev){
qDebug()<<"鼠标释放";
}
鼠标移动事件
void myLable::mouseMoveEvent(QMouseEvent *ev){
//if(ev->buttons() & Qt::LeftButton){//位操作符
qDebug()<<"鼠标移动";
// }
}
鼠标位置
ev->x();ev->y();ev->globalX();ev->globalY()
鼠标判断左右按键
if(ev->button()== Qt::LeftButton)
判断联合按键 判断move的时候左右键 – 结合&操作符判断
if(ev->buttons() & Qt::LeftButton)
QT中格式化字符串
QString str=QString("x=%1 y=%2 globalx=%3 globaly=%4" ).arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
定时器事件
利用事件 void timerEvent(QTimerEvent *event);
启动定时器 startTimer(1000);//间隔 单位毫秒
timerEvent的返回值是定时器的唯一标识,可以和event->timerId()做比较
//启动定时器
id1=startTimer(1000);//间隔 单位毫秒
id2=startTimer(2000);
void Widget::timerEvent(QTimerEvent *event){
static int num;
static int num2;
if(event->timerId()==id1){
//隔1秒
ui->label_2->setText(QString::number(num++));
}
if(event->timerId()==id2){
//隔两秒
ui->label_3->setText(QString::number(num2++));
}
}
定时器2
使用类进行设置
#include <QTimer>// 定时器类
QTimer * timer=new QTimer(this);//设置一个定时器对象
//启动定时器
timer->start(500);//毫秒 发送信号 timeout 进行监听
connect(timer,&QTimer::timeout,[=](){
static int num=1;
ui->label_4->setText(QString::number(num++));
});
//点击暂停 停止定时器
connect(ui->pushButton,&QPushButton::clicked,[=](){
timer->stop();
});
//点击继续
connect(ui->pushButton_2,&QPushButton::clicked,[=](){
timer->start();
});
事件分发
用于事件分发 也可作于拦截
bool myLable::event(QEvent *e){
//如果是鼠标按下,在事件中作拦截
if(e->type()==QEvent::MouseButtonPress){
QMouseEvent *ev=static_cast<QMouseEvent *>(e);//类的强制转化 向下转化
QString str=QString("x=%1 y=%2 globalx=%3 globaly=%4" ).arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<"event函数中鼠标按下"<<str;
return true;//true表示用户自己处理次事件,不向下分发
}
//其他事件 交给父类处理 默认处理
return QLabel::event(e);
}
QPainter绘图
绘图事件
void painEvent()
声明一个画家对象QPinter(this) this指定绘图设备
画线,画园,画矩形,画文字
设置画笔QPen 设置画笔宽度、风格
设置画刷QBrush设置画刷宽度、风格
//重写paintEvent函数
void Widget::paintEvent(QPaintEvent *event){
//实例化画家对象,this指定绘画设备
QPainter Painter(this);
//设置画笔
QPen pen(QColor(157,45,45));
//设置笔的宽度
pen.setWidth(2);
//设置画笔风格
pen.setStyle(Qt::DotLine);
//设置笔刷
QBrush brush(Qt::Dense2Pattern);
//使用画笔
Painter.setPen(pen);
//使用笔刷
Painter.setBrush(brush);
//画一条直线
Painter.drawLine(QPoint(0,0),QPoint(100,100));
//画一个圆
Painter.drawEllipse(QPoint(100,100),50,50);
//画一个矩形
Painter.drawRect(20,20,45,45);
//画文字
Painter.drawText(QRect(10,200,100,50),"天天吃荔枝");
}
抗锯齿:
Painter.drawEllipse(QPoint(50,50),43,43);
//抗锯齿能力 效率较低
Painter.setRenderHint(QPainter::Antialiasing);
Painter.drawEllipse(QPoint(150,150),43,43);
对画家进行移动:
移动画家位置:Painter.translate(100,20);
对画家位置进行保存:Painter.save();
对画家位置进行还原:Painter.restore();
手动调用绘图事件:updata();
利用画家画图片 Painter.drawPixmap(0,0,QPixmap(":/image/add.png"));
绘图设备
Pixmap绘图设备 专门为平台做了显示的优化
#include <QPixmap>
QPixmap pix(300,300);
//填充颜色
pix.fill(Qt::white);
QPainter painter(&pix);
painter.setPen(QPen(Qt::green));
painter.drawEllipse(QPoint(50,50),45,45);
//保存
pix.save("/home/raoxu/pix.png");
QImage 对像素进行修改
当绘图设备时,操作与Pixmap类似,多了一个对format的选择 :
QImage img(300,300,QImage::Format_RGB32);
像素操作时,重写绘图事件
void Widget::paintEvent(QPaintEvent *event){
//利用QImage,对像素进行修改
QPainter painter(this);
QImage img;
img.load(":/image/open.jpg");
//修改像素点
for(int i=40;i<100;i++){
for(int j=40;j<100;j++){
//修改像素点
QRgb rgb_value=qRgb(255,234,0);
img.setPixel(i,j,rgb_value);
}
}
painter.drawImage(0,0,img);
}
QPicture 绘图设备,可以记录和重现绘图指令
记录指令,在类构造函数中
//记录绘图指令
QPicture pic;
QPainter painter;
painter.begin(&pic);//开始往pic画画
painter.setPen(QPen(Qt::cyan));
painter.drawEllipse(QPoint(50,50),45,45);
painter.end();//结束绘画
//保存到磁盘
pic.save("/home/raoxu/pic.z");
再绘图事件中重现
void Widget::paintEvent(QPaintEvent *event){
//重现绘图指令
QPainter painter(this);
QPicture pic;
pic.load("/home/raoxu/pic.z");
painter.drawPicture(0,0,pic);
}
Qfile对文件进行操作
文件内容读取
QFile 进行读写操作
QFile file( path文件路径)
读:
file.open(打开方式); QIODevice::ReadOnly
全部读取 QByteArray array= file.readAll(); 按行读 file.readLine(); file.atEnd()判断是否读到文件尾
默认支持的编码 :UTF-8
利用编码格式类 指定编码格式
关闭文件对象 close();
写:
file.open(打开方式);QIODevice::Append
file.write(内容);
关闭文件对象 close();
//编码格式类
//QTextCodec*codec=QTextCodec::codecForName("gbk");
//读取内容
//QFile默认支持utf-8
QFile file(fileName);
//设置打开方式
file.open(QIODevice::ReadOnly);
//QByteArray array= file.readAll();
QByteArray arrays;
//一次读取一行
while(!file.atEnd()){
arrays +=file.readLine();
}
//将读到的数据放入textEdit中
ui->textEdit->setText(arrays);
//转码
//ui->textEdit->setText(codec->toUnicode(array));
//对文件对象进行关闭
file.close();
//进行写文件
file.open(QIODevice::Append);
file.write("啊啊啊啊啊啊啊啊啊");
file.close();
文件信息读取
QfileInfo读取文件信息
QfileInfo info(路径);
文件后缀:info.suffix();
文件创建日期:info.created().toString(“yyyy-MM-dd-hh-mm-ss”);
文件最后修改日期:info.lastModified().toString(“yyyy-MM-dd-hh-mm-ss”);