注*:以下笔记内容根据黑马程序员教程所做,传至线上仅为方便实时查阅,因个人疏忽、学艺不精或可导致笔记内容有误,望请阅览者不吝指出*
文章目录
QT笔记
01_Practice
1、初识
2、对象树
当创建的对象在堆区时,如果指定的父亲是Object派生下的类或其子类派生下来的类,可以不用管理释放操作,将对象会放入到对象树中
3、信号与槽
连接函数 connect (参数1,参数2,参数3,参数4)
参数1:信号的发送者
参数2:发送的信号
参数3:信号接收者
参数4:信号处理(槽)
//创建第一个按钮
QPushButton* btn = new QPushButton;
btn->show();//以顶层方式弹出控件
btn->setParent(this);
btn->setText("按钮1");
//创建第二个按钮
QPushButton* btn2 = new QPushButton("按钮2",this);//该方式是按照控件大小创建窗口
//移动按钮2
btn->move(100, 100);
btn2->move(100, 200);
//重置窗口大小
resize(400, 600);
//固定窗口大小
setFixedSize(400, 600);
//设置窗口标题
setWindowTitle("窗口1");
//信号与槽
//参数1 信号的发送者 参数2 发送的信号(函数的地址)
//参数3 信号的接收者 参数4 处理的槽函数
connect(btn2, &QPushButton::clicked, this, &myPractice::close );
02_Practice-信号和槽
1、自定义信号和槽
自定义信号,返回值为void,需要声明,不需要实现,可有参数
自定义槽函数,返回值为void,需要声明,需要实现,可有参数
案例-下课后-老师触发饿了信号-学生响应-请吃饭
自建学生/老师类
//teacher.h文件
class Teacher : public QObject
{
Q_OBJECT
public:
Teacher(QObject *parent);
~Teacher();
signals:
//自定义信号,返回值为void,只需写声明,不需要实现,可有参即重载
void hungry();
};
//student.h文件
class Student : public QObject
{
Q_OBJECT
public:
Student(QObject *parent);
~Student();
//槽函数 返回void,需要写声明也需要写实现
void Treat();
};
//student.cpp文件
Student::Student(QObject *parent)
: QObject(parent)
{
}
Student::~Student()
{
}
void Student::Treat()
{
qDebug() << "请老师吃饭";
}
//widget.h文件
#include <QtWidgets/QWidget>
#include "ui_Widget.h"
#include"Teacher.h"
#include"Student.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = Q_NULLPTR);
private:
Ui::WidgetClass ui;
//老师、学生对象声明
Teacher* yq;
Student* st;
void ClassIsover();
};
//widget.cpp文件
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
//创建老师、学生对象
this->yq = new Teacher(this);
this->st = new Student(this);
//做连接
connect(yq, &Teacher::hungry, st, &Student::Treat);
ClassIsover();
}
void Widget::ClassIsover()
{
//emit触发函数
emit yq->hungry();
}
2、当自定义信号和槽出现重载,需要利用函数指针明确指向函数地址
//有参连接
//函数指针->函数地址
//函数指针声明,注:声明成员函数指针时前面要加相应的作用域
void(Teacher:: * teacherSignal)(QString) = &Teacher::hungry;
void(Student:: * studentSlot)(QString) = &Student::Treat;
connect(yq, teacherSignal, st, studentSlot);
ClassIsover();
//增加一个下课的按钮,再触发下课
QPushButton* btn = new QPushButton(u8"下课", this);
this->resize(600,400);
//点击按钮,触发下课
connect(btn, &QPushButton::clicked, this &Widget::ClassIsover);
3、Qstring转char*过程,先通过.ToUf8()转为QByteArray,再通过.Data()转为char*
qDebug() << "请老师吃饭,老师要吃:"<<foodName.toUtf8().data();
4、信号连接信号
断开信号disconnect()
一个信号可以连接多个槽函数
多个信号可连接同一个槽函数
信号和槽函数的参数类型,需一一对应
信号的参数个数可以多于槽的参数个数
创建“下课”按钮,触发下课之后,再触发老师饿了信号
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
//创建老师、学生对象
this->yq = new Teacher(this);
this->st = new Student(this);
//增加一个下课的按钮,再触发下课
QPushButton* btn = new QPushButton(u8"下课", this);
this->resize(600,400);
//如果是无参连接,即为信号连接信号
void(Teacher:: * teacherSignal2)(void) = &Teacher::hungry;
void(Student:: * studentSlot2)(void) = &Student::Treat;
connect(yq, teacherSignal2, st, studentSlot2);
connect(btn, &QPushButton::clicked, yq,teacherSignal2);
//断开信号
disconnect(yq, teacherSignal2, st, studentSlot2);
}
5、lambda表达式:用于定义并创建匿名的函数对象
mutable关键字,用于修饰值传递的变量,修改的是拷贝,而非本体
实现点击按钮,关闭窗口
//[]标识符 匿名函数 =值传递 &引用传递
//()参数
//{}实现体2
//返回值->
[=](){}
03_Practice-QmainWidow
1、QMainWindow
一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个锚接部件(dock sidgets)、一个状态栏(status bar)、及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器、图片编辑器等
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
resize(600, 400);
//菜单栏创建,最多仅有一个
QMenuBar* bar = menuBar();
//放入窗口
setMenuBar(bar);
//创建菜单
QMenu*fileMenu=bar->addMenu(u8"文件");
QMenu* editMenu = bar->addMenu(u8"编辑");
//创建菜单项
fileMenu->addAction(u8"新建");
QAction* saveMenu = fileMenu->addAction(u8"保存");//创建保存按钮,并用saveMenu去接收
//添加分隔符
fileMenu->addSeparator();
fileMenu->addAction(u8"打开");
//工具栏 可以有多个
QToolBar* toolBar = new QToolBar(this);
addToolBar(Qt::LeftToolBarArea, toolBar);//将状态栏默认设置为左边停靠
//设置只允许左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
//设置浮动
toolBar->setFloatable(false);
//设置移动
toolBar->setMovable(false);
//在工具栏中设置内容
toolBar->addAction(saveMenu);
//添加控件
QPushButton* btn = new QPushButton("aa", this);
toolBar->addWidget(btn);//将按钮放进去
//状态栏 最多有一个
QStatusBar* stBar = statusBar();
//放到窗口中
setStatusBar(stBar);
//放置标签控件
QLabel* label = new QLabel(u8"提示信息", this);
stBar->addWidget(label);
//放置到最右边
QLabel* label2 = new QLabel(u8"右侧提示信息", this);
stBar->addPermanentWidget(label2);
//铆接部件(浮动窗口) 可以有多个,根据中心部件来定
QDockWidget* dockWidget = new QDockWidget(u8"浮动",this);
addDockWidget(Qt::BottomDockWidgetArea,dockWidget);
//设置中心部件 仅有一个
QTextEdit* textEdit = new QTextEdit(this);
setCentralWidget(textEdit);
//ui.setupUi(this);
}
04_Practice——资源文件&对话框
1、资源文件
步骤:1)将图片文件拷贝到项目文件夹下;
2)在.qrc文件中点击add按钮,先编辑前缀名,再编辑file
3)使用":+前缀名+文件名"
//添加图标-固定文件夹路径
ui.actionnew->setIcon(QIcon("D:/Qt/myPractice/04_Practice/04_Practice/Images/Edit.JPG"));
//使用QT加载资源":+前缀名+文件名"
ui.actionnew->setIcon(QIcon(":/Images/File.jpg"));
ui.menu_2->setIcon(QIcon(":/Images/Edit.jpg"));
2、自定义对话框
分类:1)模态对话框:不可以对其它窗口进行操作
2)非模态对话框:可以对其它窗口进行操作
//点击新建按钮,弹出对话框
connect(ui.actionnew, &QAction::triggered, [=]() {
//模态对话框
QDialog dlg(this);
dlg.exec();//阻塞
dlg.resize(150, 150);
});
connect(ui.actionopen, &QAction::triggered, [=]() {
//非模态对话框
QDialog *dlg2=new QDialog(this);
dlg2->show();
dlg2->resize(200, 200);
//由于dlg2是new出来的,(防止一闪而过创建)在堆区,仅关掉对话框不会被释放,故用此释放
dlg2->setAttribute(Qt::WA_DeleteOnClose);
3、标准对话框
——qt内置的一系列对话框,用于简化开发
对话框 | 常用静态函数名称 | 函数功能 |
---|---|---|
QFileDialog 文件对话框 | QString getOpenFileName() QStringList getOpenFileNames() QString getSaveFileName() QString getExistingDirectory() QUrl getOpenFileUrl() | 选择打开一个文件 选择打开多个文件 选择保存一个文件 选择一个己有的目录 选择打幵一个文件,可选择远程网络文件 |
QcolorDialog 颜色对话框 | QColor getColor() | 选择颜色 |
QFontDialog 字体对话框 | QFont getFont() | 选择字体 |
QinputDialog 输入对话框 | QString getText() int getlnt() double getDouble() QString getltem() QString getMultiLineText() | 输入单行文字 输入整数 输入浮点数 从一个下拉列表框中选择输入 输入多行字符串 |
QMessageBox 消息框 | StandardButton information() StandardButton question() StandardButton waming() StandardButton critical() void about() void aboutQt() | 信息提示对话框 询问并获取是否确认的对话框 警告信息提示对话框 错误信息提示对话框 设置自定义信息的关于对话框 关于Qt的对话框 |
//消息对话框
connect(ui.actioncopy, &QAction::triggered, [=]() {
//错误
QMessageBox::critical(this, u8"提示", u8"操作错误");
//信息
QMessageBox::information(this, u8"信息", u8"提示");
//提问对话框,参数类型(父亲,标题,内容,按键名字/类型,默认关联回车按钮)
/QMessageBox::question(this, u8"问题", u8"提问",QMessageBox::Save|QMessageBox::Cancel);
//如何判断用户选择
if (QMessageBox::Save == QMessageBox::question(this, u8"问题", u8"提问", QMessageBox::Save | QMessageBox::Cancel))
{
qDebug() << u8"选择的是保存";
}
else
{
qDebug() << u8"选择的是取消";
}
2)颜色对话框
#include<qColorDialog>
QColorDialog::getColor(QColor(255, 0, 0));
//用color接收选择的颜色
QColor color=QColorDialog::getColor(QColor(255, 0, 0));
qDebug()<<"r="<<color.red();
3)文件对话框
#include<qFileDialog>
//参数类型(父亲,标题,默认打开路径,过滤的文件格式)
QFileDialog::getOpenFileName(this,"打开文件","<默认路径>","(*.txt)");
05_Layout
1、界面布局
布局方式——窗口美化,选取widget进行布局,水平布局/垂直布局/栅格布局
06_Practice——控件
1、按钮组
1)pushbutton,添加图片可通过文件夹资源,在Icon选项
2)toolbutton,图片+文字效果,添加图片在Icon,名称在text,显示这个文本在QTollButton——toolButtonStyle——ToolButtonTextBesideIcon,选择autoRise,可以使其背景透明
3)Radiobutton,选项框,多个选项框一般放在GroupBox,若想提前设定默认值,在代码中设定:
ui.rBtnMan->setChecked(true);
4)Check Box,信号:监听状态stateChanged,2为选中,0为未选择,1为半选
connect(ui.checkBox, &QCheckBox::stateChanged, [=](int statue) {
qDebug() << statue;
});
2、QListWidget控件——列表容器
//第一种——QListWidgetItem是每一行的内容
QListWidgetItem* item = new QListWidgetItem(u8"床前明月光");
QListWidgetItem* item2 = new QListWidgetItem(u8"疑是地上霜");
//将内容放入控件中
ui.listWidget->addItem(item);
//设置对齐方式-水平居中
item->setTextAlignment(Qt::AlignHCenter);
//第二种——无法调整居中方式
//QstringList容器
QStringList list;
list << u8"床前明月光" << u8"疑是地上霜";//重载<<符号,用来连接
ui.listWidget->addItems(list);//一次性添加
3、QTreeWidget树控件
//设置水平头
ui.treeWidget->setHeaderLabels(QStringList() << u8"英雄" << u8"介绍");
//创建根节点
QTreeWidgetItem* liItem = new QTreeWidgetItem(QStringList() << u8"力量");
QTreeWidgetItem* mjItem = new QTreeWidgetItem(QStringList() << u8"敏捷");
QTreeWidgetItem* zlItem = new QTreeWidgetItem(QStringList() << u8"智力");
//加载顶层节点
ui.treeWidget->addTopLevelItem(liItem);
ui.treeWidget->addTopLevelItem(mjItem);
ui.treeWidget->addTopLevelItem(zlItem);
//追加子节点
QTreeWidgetItem* liItem1 = new QTreeWidgetItem(QStringList() << u8"111");
liItem->addChild(liItem1);
QTreeWidgetItem* mjItem1 = new QTreeWidgetItem(QStringList() << u8"222");
mjItem->addChild(mjItem1);
QTreeWidgetItem* zlItem1 = new QTreeWidgetItem(QStringList() << u8"333");
zlItem->addChild(zlItem1);
4、QTableWidget控件
//设置列数
ui.tableWidget->setColumnCount(3);
//设置水平表头
ui.tableWidget->setHorizontalHeaderLabels(QStringList() << u8"姓名" << u8"性别" << u8"年龄");
//设置行数
ui.tableWidget->setRowCount(5);
//设置正文
QStringList nameList;
nameList << u8"亚瑟" << u8"赵云" << u8"张飞" << u8"关羽" << u8"花木兰";
QList<QString>sexList;
sexList << u8"男" << u8"男" << u8"男" << u8"男" << u8"女";
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)));
//int转string
ui.tableWidget->setItem(i, col++, new QTableWidgetItem(QString::number(i+18)));
}
5、其它常用控件
1)srcoll area滚动区域
2)tool box,修改文本名称——currentItemText
3)tab widget,类似于多网页窗口
4)stack widget,可用于设置多页切换,cureentInse是每一页的索引
//设置默认界面定位
ui.stackedWidget->setCurrentIndex(0);
//设置三页切换模式
connect(ui.btn_SW, &QPushButton::clicked, [=]() {
ui.stackedWidget->setCurrentIndex(0);
});
connect(ui.btn_TB, &QPushButton::clicked, [=]() {
ui.stackedWidget->setCurrentIndex(1);
});
connect(ui.btn_GB, &QPushButton::clicked, [=]() {
ui.stackedWidget->setCurrentIndex(2);
});
5)Frame边框
6)dock widget浮动窗口
7)Combo Box下拉框
//语法
ui.comboBox->addItem(u8"学生");
//点击按钮 选中拖拉机选项
connect(ui.btn_ch3, &QPushButton::clicked, [=]() {
//ui.comboBox->setCurrentIndex(2);
ui.comboBox->setCurrentText(u8"教导主任");
});
8)Line Edit 单行文本输入框
9)Text Edit 多行文本输入框,支持文字颜色变换加粗
10)Plain Text Edit 不支持文字颜色变换加粗
11)Label可以容纳文本,也可以装图片,也可以显示动图
//利用QLabel装图片
ui.lal_pic->setPixmap(QPixmap(":/Images/Edit.jpg"));
//显示动图,需加载头文件Qmovie
QMovie *mov=new QMovie("文件名");
ui.lal_mov->setMovie(movie);
//播放动图
movie->start();
07_Practice——自定义控件封装、鼠标事件
1、Spin Box和Horizontal Slider
封装操作:添加qt设计师界面类(.h; .cpp; .ui),在widget中使用自定义控件,右键单击“提升为”,写明类名
2、Qt中的鼠标事件
鼠标进入——enterEvent
鼠标离开——leaveEvent
鼠标按下——mousePressEvent
鼠标释放——mouseReleaseEvent
鼠标移动——mouseMoveEvent
坐标捕获ev->x();ev->y();
ev->button();可判断所有按键Qt::leftButton/RightButton
ev->buttons()可判断组合按键
3、定时器
第一种
利用事件void timeEvent(QTimeEvent*ev)
启动定时器startTimer(1000)毫秒单位
timerEvent的返回值是定时器的唯一标识
第二种
利用定时器类<Qtimer.h>
创建定时器对象啊 Qtimer *timer=new Qtimer(this)
启动定时器 timer->start(毫秒)
每隔一定事件 发送信号 timeout
4、事件分发****器
bool event(Qevent *ev) 返回值为bool类型,如果返回的是true,代表用户要处理这个事件,不向下分发事件
bool myLabel::event(QEvent* e)
{
if (e->type() == QEvent::MouseButtonPress)
{
QMouseEvent* ev = static_cast<QMouseEvent*>(e);//将e由Qevernt类转为QmouseEvent类
QString str = QString(u8"event函数中:x=%1 y=%2 Gx=%3 Gy=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug() << str;
return true;//表示用户自己处理,不向下分发
}
return QLabel::event(e);//其它事件 交给父类处理
}
5、事件过滤器
在程序分发到event事件之前再做一次高级使用,步骤:
1)给控件安装事件过滤器
2)重写eventfilter函数
6、QFile文件读写
qt默认支持文件为utl-8格式
gbk格式可进行转换
//点击按钮,打开文件
connect(ui.pushButton, &QPushButton::clicked, [=]() {
QString path = QFileDialog::getOpenFileName(this, u8"打开文件", "C:\\Users\\Amber\\Desktop\\XX");
//将路径名放入到linwEdit中
ui.lineEdit->setText(path);
//编码格式类
QTextCodec* codec = QTextCodec::codecForName("doc");
//将读取的内容放入到textEdit中
QFile file(path);
//设置打开方式
file.open(QIODevice::ReadOnly);
//将读取内容用array存放
QByteArray array = file.readAll();
//将内容放入到textEdit中
ui.textEdit->setText(codec->toUnicode(array));//读取gbk格式文件
file.close();
});
开文件
connect(ui.pushButton, &QPushButton::clicked, = {
QString path = QFileDialog::getOpenFileName(this, u8"打开文件", “C:\Users\Amber\Desktop\XX”);
//将路径名放入到linwEdit中
ui.lineEdit->setText(path);
//编码格式类
QTextCodec* codec = QTextCodec::codecForName("doc");
//将读取的内容放入到textEdit中
QFile file(path);
//设置打开方式
file.open(QIODevice::ReadOnly);
//将读取内容用array存放
QByteArray array = file.readAll();
//将内容放入到textEdit中
ui.textEdit->setText(codec->toUnicode(array));//读取gbk格式文件
file.close();
});