文章目录
信号与槽
按钮控件与信号
// 创建按钮对象及其实例,参数一为按钮名称,参数二为将按钮控件镶嵌到主窗口当中
QPushButton* btn=new QPushButton("close",this);
// 重新设置主窗口大小
resize(600,400);
// 移动按钮位置,按钮创建时默认为原点
btn->move(width()/2,height()/2);
// 设置主窗口名称
this->setObjectName("按钮实验");
// 信号控件,参数:发送信号者,发送的信号,接受信号者,接受的信号
connect(btn,&QPushButton::clicked,this,&myWidget::close);
自定义信号
#include "mywidget.h"
#include "ui_mywidget.h"
#include<QPushButton>
myWidget::myWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::myWidget)
{
ui->setupUi(this);
//创建教师对象
this->zt=new Teacher(this);
//创建学生对象
this->st=new Student(this);
connect(zt,&Teacher::hungry,st,&Student::treat);
classIsOver();
classIsOver();
}
void myWidget::classIsOver()
{
//emit发射信号
emit zt->hungry();
}
myWidget::~myWidget()
{
delete ui;
}
#include "student.h"
#include<QDebug>
Student::Student(QObject *parent) : QObject(parent)
{
}
void Student::treat()
{
qDebug()<<"请老师吃饭"<<endl;
}
自定义信号与槽发生重载的问题
//创建教师对象
this->zt=new Teacher(this);
//创建学生对象
this->st=new Student(this);
//函数指针->函数地址
void(Teacher::*teacherSingal)(QString)=&Teacher::hungry;
void(Student::*studentSingal)(QString)=&Student::treat;
connect(zt,teacherSingal,st,studentSingal);
classIsOver();
#include "student.h"
#include<QDebug>
Student::Student(QObject *parent) : QObject(parent)
{
}
void Student::treat()
{
qDebug()<<"请老师吃饭"<<endl;
}
void Student::treat(QString foodName)
{
qDebug()<<"请老师吃:"<<foodName<<endl;
}
void myWidget::classIsOver()
{
//emit发射信号
emit zt->hungry("宫保鸡丁");
}
按钮触发信号
QPushButton* btn=new QPushButton("下课",this);
this->resize(600,400);
//点击下课按钮触发宫保鸡丁时间
connect(btn,&QPushButton::clicked,this,&myWidget::classIsOver);
void myWidget::classIsOver()
{
//emit发射信号
emit st->treat("宫保鸡丁");
}
信号链接信号
// 无参信号与槽链接
void(Teacher::*teacherSingal)(void)=&Teacher::hungry;
void(Student::*studentSingal)(void)=&Student::treat;
connect(zt,teacherSingal,st,studentSingal);
// 信号链接信号,按钮信号链接教师信号
connect(btn,&QPushButton::clicked,zt,teacherSingal);
}
void myWidget::classIsOver()
{
//emit发射信号
emit zt->hungry();
// emit zt->hungry("宫保鸡丁");
// emit st->treat("宫保鸡丁");
}
lamdba表达式
// lamdba表达式
// [外部变量捕获方式](形参)mutable->返回类型{函数体}(实参);
// [外部变量捕获方式]:当{}中使用外部变量时,需要在此声明使用的外部变量,称其为捕获,捕获方式有,
// 值传递[a]:该方式传递外部变量进入lamdba表达式内部使用时,默认为const方式,即不可改变传递进来的外部变量的值,
// 若需要改变,则需要使用关键字mutable,但注意,此刻改变的并非外部变量本体的值,而是拷贝进lamdba的值
// 引用传递[&]:使用引用方式传递外部变量进入lamdba表达式,将lamdba表达式内使用的外部变量与本体外部变量进行绑定
// 自推导方式[=]
// (形参):lamdba表达式函数形参
// {函数体}:lamdba表达式具体实现
// (实参):传递给形参的值,{}中使用return语句时必须使用该实参
QPushButton* btn1=new QPushButton("btn1",this);
QPushButton* btn2=new QPushButton("btn2",this);
QPushButton* btn3=new QPushButton("btn3",this);
resize(600,400);
btn2->move(300,200);
btn3->move(200,300);
int m=10;
qDebug()<<"start:"<<m<<endl;
connect(btn1,&QPushButton::clicked,this,[=](){qDebug()<<m+10<<endl;});
connect(btn2,&QPushButton::clicked,this,[m]()mutable{qDebug()<<m+20<<endl;});
qDebug()<<"next:"<<m<<endl;
#if 1
int ret;
ret=[m]()mutable->int{return m+30;}();//值传递
qDebug()<<"ret_m:"<<ret<<endl;//40
ret=[=]()->int{return m+40;}();//自推导传递
qDebug()<<"ret_=:"<<ret<<endl;//50
ret=[](int a,int b)->int{return a+b;}(2,3);
qDebug()<<"ret_a+b:"<<ret<<endl;//5
ret=[](int x)->int{return [](int y)->int{return y*2;}(x)+6;}(5);
qDebug()<<ret<<endl;//16
#endif
//利用lamdba表达式进行信号传递
QPushButton* btn_lam=new QPushButton("关闭",this);
btn_lam->move(100,0);
connect(btn_lam,&QPushButton::clicked,this,[=](){
this->close();
// emit st->treat("宫保鸡丁");
// btn_lam->setText("aaa");//效果:点击“关闭”按钮后,按钮名称自动改为“aaa”
});
控件
菜单栏与工具栏
resize(600,400);
// 创建菜单栏QMenuBar,最多有一个
QMenuBar* bar=menuBar();
// 将菜单栏放入窗口中
setMenuBar(bar);
// 创建菜单QMenu
QMenu* fileMenu=bar->addMenu("文件");
QMenu* editMenu=bar->addMenu("编辑");
// 创建菜单项QAction
fileMenu->addAction("新建");
fileMenu->addSeparator();//添加菜单栏分割线
fileMenu->addAction("打开");
fileMenu->addSeparator();//添加菜单栏分割线
fileMenu->addAction("保存");
fileMenu->addSeparator();//添加菜单栏分割线
fileMenu->addAction("关闭");
fileMenu->addSeparator();
//工具栏
QToolBar* toolBar=new QToolBar(this);
//设置默认停靠区域
addToolBar(Qt::LeftToolBarArea,toolBar);
// 后期设置,左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea);
// 设置浮动
toolBar->setFloatable(false);//工具栏将不能浮动在窗口表面
//设置移动
toolBar->setMovable(false);//工具栏将不能移动,此时上边左右停靠的设置将失效
// 工具栏中添加内容
// 创建内容
QAction* helpAction=fileMenu->addAction("帮助");//将菜单栏中的内容添加到工具栏中
QAction* processAction=fileMenu->addAction("项目");
// 将内容添加到工具栏中
toolBar->addAction(helpAction);
toolBar->addSeparator();//添加工具栏分割线
toolBar->addAction(processAction);
toolBar->addSeparator();//添加工具栏分割线
//在工具栏中添加控件
QPushButton* btn=new QPushButton("设置",this);
toolBar->addWidget(btn);
tips:
//菜单栏,最多有一个
QMenuBar* bar=menuBar();
setMenuBar(bar);
//添加菜单内容
QMenu* fileMenu=bar->addMenu("文件");
//添加菜单项
QAction* newAction=fileMenu->addAction("创建");
//添加分割线
fileMenu->addSeparator(newAction);
//工具栏,可以有多个
QToolBar* toolBar=new QToolBar("this");
//设置默认停靠区域
addToolBar(Qt::leftBarArea,toolBar);
//后期设置停靠区域,浮动,移动,在工具栏中添加内容,控件
模态与非模态对话框
//点击创建按钮,弹出一个对话框
connect(ui->actionNew,&QAction::triggered,[=](){
//模态对话框,不可以对其他窗口进行操作
#if 0
QDialog dlg(this);
dlg.resize(200,100);
dlg.exec();
#endif
#if 0
//非模态对话框,可以对其他窗口进行操作
QDialog* dlg2=new QDialog(this);
dlg2->resize(200,100);
dlg2->show();
#endif
消息对话框
//点击创建按钮,弹出一个对话框
connect(ui->actionNew,&QAction::triggered,[=](){
//错误对话框,参数:父类,标题,提示内容
// QMessageBox::critical(this,"critical","错误");
//信息对话框
// QMessageBox::information(this,"info","信息");
//提问对话框,参数:1.父类,2.标题,3.提示内容,4.按键类型,5.默认关联回车键
// QMessageBox::question(this,"ques","提问",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel);
// if(QMessageBox::Save==QMessageBox::question(this,"ques","提问",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel))
// {
// qDebug()<<"选择的按键类型是保存"<<endl;
// }
// else
// {
// qDebug()<<"选择的按键类型是选择取消"<<endl;
// }
//警告对话框
QMessageBox::warning(this,"warning","警告");
其他对话框
connect(ui->actionnew,&QAction::triggered,[=](){
//颜色对话框
// QColor color=QColorDialog::getColor(QColor(0,255,0));
// qDebug()<<"red:"<<color.red()<<"green:"<<color.green()<<"blue:"<<color.blue()<<endl;
//文件对话框,参数:父亲,标题,默认文件路径,筛选的文件类型
//返回值为文件路径
// QString str=QFileDialog::getOpenFileName(this,"openFile","C:\Users\Administrator\Desktop","*.md");
// qDebug()<<str<<endl;
//字体对话框
bool flag;
QFont font=QFontDialog::getFont(&flag,QFont("仿宋",36));
qDebug()<<"字体 "<<font.family()<<"大小 "<<font.pointSize()<<"是否加粗 "<<font.bold()<<"是否倾斜 "<<font.italic()<<endl;
});
UI布局设计
tips:
1.选取widget进行布局,水平、垂直、栅格
2.默认窗口与控件之间存在9的间隙,可以调整layoutLeftMargin
3.利用弹簧进行布局
按钮控件组
//默认性别单选框为男
ui->rBtnMan->setChecked(true);
//点击”女“,打印信息
connect(ui->rBtnWoman,&QRadioButton::clicked,[=](){
// qDebug()<<QString::fromUtf8("女")<<endl;
qDebug()<<"女"<<endl;
});
//点击”操作系统“显示状态码,0表示未选中,2表示选中
connect(ui->boxOS,&QCheckBox::stateChanged,[=](int state){
qDebug()<<state<<endl;
});
tips:
按钮组:
QPushButton:常用按钮
QToolButton:工具按钮,用于显示图片,如想显示文字,修改风格toolButtonStyle,凸起风格:autoRaise
QRadioButton:单选按钮,ui->rBtnMan->setChecked(true);//设置默认选项
QCheckBox:多选按钮,监听状态QStateChecked,0未选中,1半选,2选中
QListWidget列表容器
//利用listwidget写诗
QListWidgetItem* item=new QListWidgetItem("锄禾日当午");
ui->listWidget->addItem(item);//添加一句话
item->setTextAlignment(Qt::AlignHCenter);//设置对其方式为居中
QStringList list;
list<<"我见青山多妩媚"<<"料青山见我应如是!";
ui->listWidget->addItems(list);//添加多句话
ui->listWidget->addItems(QStringList()<<"自其变者而观之,则天地曾不能以一瞬"<<"自其不变者而观之,则物与我皆无尽也");
treeWidget树控件
//设置水平头
ui->treeWidget->setHeaderLabels(QStringList()<<"英雄"<<"英雄自我介绍");
//设置顶层节点
QTreeWidgetItem* strongItem=new QTreeWidgetItem(QStringList()<<"力量");
QTreeWidgetItem* speedItem=new QTreeWidgetItem(QStringList()<<"速度");
QTreeWidgetItem* inteligenceItem=new QTreeWidgetItem(QStringList()<<"智力");
//加载顶层节点
ui->treeWidget->addTopLevelItem(strongItem);
ui->treeWidget->addTopLevelItem(speedItem);
ui->treeWidget->addTopLevelItem(inteligenceItem);
//追加子节点
QTreeWidgetItem* l1=new QTreeWidgetItem(QStringList()<<"刚被猪"<<"前排坦克。。。。。。");
strongItem->addChild(l1);
tableWidget表格控件
//设置列数
ui->tableWidget->setColumnCount(3);
//设置水平表头
ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"姓名"<<"性别"<<"年龄");
//设置行数
ui->tableWidget->setRowCount(5);
//设置正文
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)));
//将数字转换为QString
ui->tableWidget->setItem(i,col++,new QTableWidgetItem(QString::number(i+18)));
}
其他控件介绍
//栈控件使用
//设置默认定位
ui->stackedWidget->setCurrentIndex(2);
//点击按钮跳转到TabWidget控件页面
connect(ui->btnTab,&QPushButton::clicked,[=](){
ui->stackedWidget->setCurrentIndex(0);
});
//点击按钮跳转到scrollArea控件页面
connect(ui->btnScroll,&QPushButton::clicked,[=](){
ui->stackedWidget->setCurrentIndex(1);
});
//点击按钮跳转到toolBox控件页面
connect(ui->btnTool,&QPushButton::clicked,[=](){
ui->stackedWidget->setCurrentIndex(2);
});
//下拉框
ui->comboBox->addItems(QStringList()<<"宝马"<<"奔驰"<<"拖拉机");
//选中“拖拉机”按钮跳转到下拉框拖拉机
connect(ui->btnSelect,&QPushButton::clicked,[=](){
// ui->comboBox->setCurrentIndex(2);
ui->comboBox->setCurrentText("拖拉机");
});
tips:
栈控件:ui->stackedWidget->setCurrentIndex();
下拉框:ui->comboBox->addItems(QStringList()<<"奔驰"<<"宝马");
Qlabel显示图片:ui->labelImage->setPixmap("图片路径");
Qlabel显示动图:ui->LabenImage->setMoive();
自定义控件
class smallWidget : public QWidget
{
Q_OBJECT
public:
explicit smallWidget(QWidget *parent = nullptr);
~smallWidget();
//设置数值
void setNum(int num);
//获取数值
int getNum();
private:
Ui::smallWidget *ui;
};
smallWidget::smallWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::smallWidget)
{
ui->setupUi(this);
//QSpinBox翻滚,QSlider跟着移动
void(QSpinBox::* spSingal)(int)=&QSpinBox::valueChanged;
connect(ui->spinBox,spSingal,ui->horizontalSlider,&QSlider::setValue);
//QSlider移动,QSpinBox跟着翻滚
connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);
}
void smallWidget::setNum(int num)
{
ui->spinBox->setValue(num);
}
int smallWidget::getNum()
{
return ui->spinBox->value();
}
smallWidget::~smallWidget()
{
delete ui;
}
myWidget::myWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::myWidget)
{
ui->setupUi(this);
//点击按钮获取数值
connect(ui->btnGetNum,&QPushButton::clicked,[=]()
{
qDebug()<<ui->widget->getNum();
});
//点击按钮设置进度条到一半数值
connect(ui->btnSetNum,&QPushButton::clicked,[=](){
ui->widget->setNum(50);
});
}
事件
鼠标事件
#include "mylabel.h"
#include<QDebug>
#pragma execution_character_set("utf-8")
#include<QMouseEvent>
myLabel::myLabel(QWidget *parent) : QLabel(parent)
{
//设置鼠标跟踪状态
setMouseTracking(true);//此时只要是鼠标事件其状态都会被监听
}
void myLabel::enterEvent(QEvent *event)
{
// qDebug()<<"鼠标进入了!"<<endl;
}
void myLabel::leaveEvent(QEvent *)
{
// qDebug()<<"鼠标离开了!"<<endl;
}
void myLabel::mousePressEvent(QMouseEvent *ev)
{
//鼠标左键按下,则显示信息
if(ev->button()==Qt::LeftButton)
{
//返回鼠标在指定区域内的坐标值以及在整个窗口内的坐标值
//QString::arg()//用字符串变量参数依次替代字符串中最小数值
QString str=QString("鼠标按下了 x=%1 y=%2 gloalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
}
}
void myLabel::mouseReleaseEvent(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 myLabel::mouseMoveEvent(QMouseEvent *ev)
{
// if(ev->buttons()&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;
}
}
tips:
在UI中添加一个label ,选中label右键->提升 ->输入类名myLabel.
这就完成了对label控件的鼠标事件的重写.
定时器
class myWidget : public QWidget
{
Q_OBJECT
public:
myWidget(QWidget *parent = nullptr);
~myWidget();
int id1;
int id2;
//重写定时器事件
void timerEvent(QTimerEvent* ev );
private:
Ui::myWidget *ui;
Teacher* zt;
Student* st;
void classIsOver();
};
myWidget::myWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::myWidget)
{
ui->setupUi(this);
//启动定时器,startTimer(定时器间隔时长),返回定时器的唯一ID号
id1=startTimer(1000);
id2=startTimer(2000);
//定时器的第二种启动方式
QTimer* timer=new QTimer(this);
timer->start(500);
connect(timer,&QTimer::timeout,[=](){
static int num=1;
ui->label_3->setText(QString::number(num++));
});
//点击按钮停止定时器
connect(ui->btn,&QPushButton::clicked,[=](){
timer->stop();
});
}
//重写定时器事件
void myWidget::timerEvent(QTimerEvent* ev)//当定时器启动后,系统会自动调用该定时器事件函数
{
if(ev->timerId()==id1)
{
static int num=1;
//定时器启动后自动调用该函数,若启动的定时器ID号为1号,则在label上每隔1s自动加1并显示,QString::number将数字转换为Qstring类型数据
ui->label->setText(QString::number(num++));
}
if(ev->timerId()==id2)
{
static int num=1;
ui->label_2->setText(QString::number(num++));
}
}
事件分发器
事件过滤器
绘图事件
void myWidget::paintEvent(QPaintEvent*)
{
QPainter*painter=new QPainter(this);//实例化画家对象
//设置画笔
QPen pen(QColor(255,0,0));
//设置画笔宽度
pen.setWidth(2);
//设置画笔风格
pen.setStyle(Qt::DotLine);
//让画家使用画笔
painter->setPen(pen);
//设置画刷
QBrush brush(Qt::cyan);
//设置画刷风格
brush.setStyle(Qt::Dense7Pattern);
//让画家使用画刷
painter->setBrush(brush);
//画线
painter->drawLine(QPoint(0,0),QPoint(100,100));
//画椭圆
painter->drawEllipse(QPoint(100,100),50,50);
//画矩形
painter->drawRect(QRect(150,150,100,50));
//画文字
painter->drawText(QRect(300,400,300,300),"好好学习,天天向上");
}
QFile文件读写操作
//点击按钮,打开文件
connect(ui->btn,&QPushButton::clicked,this,[=](){
//获取文件路径
QString path=QFileDialog::getOpenFileName(this,"打开文件","C:\Users\Administrator\Desktop","*md");
//将文件路径放入到ui窗口内的lineEdit控件中
ui->lineEdit->setText(path);
//在textEdit控件中显示内容
QFile file(path);
//打开文件,设置打开方式
file.open(QIODevice::ReadOnly);
//读取文件内容
QByteArray array=file.readAll();
ui->textEdit->setText(array);//将内容显示到textEdit控件中
file.close();
//写文件
file.open(QIODevice::Append);//以追加方式写入文件
file.write("hello world");
file.close();
});
//点击按钮,打开文件
connect(ui->btn,&QPushButton::clicked,this,[=](){
//获取文件路径
QString path=QFileDialog::getOpenFileName(this,"打开文件","C:\Users\Administrator\Desktop","*md");
//将文件路径放入到ui窗口内的lineEdit控件中
ui->lineEdit->setText(path);
//编码格式类
QTextCodec* codec=QTextCodec::codecForName("gbk");//文件编码默认为utf-8,人为设定文件打开编码格式为gbk
//在textEdit控件中显示内容
QFile file(path);
//打开文件,设置打开方式
file.open(QIODevice::ReadOnly);
//读取文件内容
QByteArray array=file.readAll();
//将内容显示到textEdit控件中
ui->textEdit->setText(codec->toUnicode(array));
});
QFileIno文件信息读取
//文件信息类
QFileInfo info(文件路径);
qDebug()<<"大小:"<<info.size()<<" 文件后缀名称:"<<info.suffix()<<" 文件名称:"<<info.fileName();
qDebug()<<"创建日期:"<<info.created().toString("yyyy/MM/dd hh::mm::ss")<<endl;
qDebug()<<"最后修改日期"<<info.lastModified().toString("yyyy/MM/dd hh::mm::ss")<<endl;