QT学习笔记

Qt

“C:\Users\wang\Desktop\编程阅读书籍\my-books\C+±Qt5-范例开发大全.pdf”

文章目录

平时遇到的小问题

  • qt操作 world 加 axcontainer 模块

  • 判断相等

    int A;
    int B;
    A.compare(B) == 0
    
  • 字符串前的’R’字符

    使字符串不被转义

    const QString sql=R"(
                          CREATE TABLE IF NOT EXISTS  my_table (
                          id   INTEGER   PRIMARY KEY AUTOINCREMENT NOT NULL,
                          name CHAR (50) UNIQUE NOT NULL,
                          age  INTEGER
                          );)";
    

    如:

    “hello\nworld”

    输出为

    hello
    world
    

    R“hello\nworld”

    输出为

    hello\nworld
    

Vs 不能识别 Qt 组件问题

在项目属性页的vc++目录 -> 包含目录中增加 Qt 的 include 文件夹目录:

image-20220706163423328

解决中文乱码问题:

在头文件加上:

#pragma execution_character_set("utf-8")

或者在每一中文前面加上:QStringLiteral()

button = new QPushButton(QStringLiteral("按钮A"), this);

mainwindows.h:

#pragma once
#pragma execution_character_set("utf-8")

#include <QtWidgets/QMainWindow>
#include <QPushButton> 

#include "ui_MainWindow.h"

class MainWindow : public QMainWindow
{
	Q_OBJECT

public:
	MainWindow(QWidget *parent = Q_NULLPTR);

// 声明QPushButton
private:
	QPushButton *button;

	Ui::MainWindowClass ui;

// 声明QPushButton方法
private slots:
	void txtButton();
};

窗体应用

QRect

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 创建一个QLabel控件
    QLabel *label = new QLabel(this);
    // QLabel控件显示文字内容
    label->setText("Hekllo World");
    // 显示位置
    label->setGeometry(QRect(50,50,200,25));
}

MainWindow::~MainWindow()
{
    delete ui;
}

image-20220705113509839

QRect(参数 1,参数 2,参数 3,参数 4)

  • 参数 1:在窗体中 X 轴参数
  • 参数 2:在窗体中 Y 轴参数
  • 参数 3:QLabel 控件宽度
  • 参数 4:QLabel 控件高度
    label->setGeometry(QRect(500,50,20,25));

image-20220705113426459

固定窗体大小

设置最大、最小为同一值即可:

	// 窗体标题
    this->setWindowTitle("窗体应用");
    // 窗体最大 300*300
    this->setMaximumSize(300,300);
    // 窗体最小 300*300
    this->setMinimumSize(300,300);

image-20220705115317725

设置窗体大小和背景颜色

	// 默认窗体居中显示,通过move或setGeometry更改
	// 设置X轴100,Y轴100
    this->move(100,100);
    // 背景红色
    this->setStyleSheet("background:red");

image-20220705115701432

修改标题栏图标

	// 窗体标题
    this->setWindowTitle("窗体应用");
    // 窗体ICO图片,可以给图片取别名
    this->setWindowIcon(QIcon(":/images/qt.ico"));

image-20220705122435355

移动无边框窗体

mainwindow.h:

...
    
#include <QMouseEvent>
#include <QPushButton>

...
    
class MainWindow : public QMainWindow
{
    
	...
    
// 定义鼠标三种状态方法
protected:
    // 鼠标按下
    void mousePressEvent(QMouseEvent *e);
    // 鼠标移动
    void mouseMoveEvent(QMouseEvent *e);
    // 鼠标释放
    void mouseReleaseEvent(QMouseEvent *e);

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

// 定义QPoint对象
private:
    QPushButton *btClose;
    QPoint last;

	...
    
};

...

mainwindow.cpp:

...

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ...

    // 标题名
    this->setWindowTitle("移动无边框窗体");
    // 去掉标题栏
    this->setWindowFlags(Qt::FramelessWindowHint);

    // 实例一个按钮控件,因为去掉标题栏,窗体就没有关闭按钮了。
    // 所以自己添加一个按钮实现关闭功能
    btClose = new QPushButton(this);
    btClose->setText("关闭");
    // 按钮点击事件
    connect(btClose,SIGNAL(clicked()),this,SLOT(close()));
        
    ...
}

// 获取鼠标点定位窗体的位置
void MainWindow::mousePressEvent(QMouseEvent *e){
    last = e->globalPos();
}

void MainWindow::mouseMoveEvent(QMouseEvent *e){
    int dx = e->globalX() - last.x();
    int dy = e->globalY() - last.y();

    last = e->globalPos();
    move(x()+dx, y()+dy);
}

void MainWindow::mouseReleaseEvent(QMouseEvent *e){
    int dx = e->globalX() - last.x();
    int dy = e->globalY() - last.y();

    move(x()+dx, y()+dy);
}

...


image-20220705140020885

去掉标题栏最大、最小化按钮

	// 关闭按钮失效
    // this->setWindowFlags(Qt::FramelessWindowHint);
    // 去掉最大化、最小化按钮,保留关闭按钮
    this->setWindowFlags(Qt::WindowCloseButtonHint);

image-20220705140200303

多窗体调用

选择 qt -> qt设计师界面类:

image-20220705140515255

选择mainwindow,下一步:

image-20220705140555324

修改类名为mainwindow2:

image-20220705140640804

mainwindow.h:

...
    
#include <QPushButton> // 引入按钮类头文件
#include <mainwindow2.h> // 引入mainwindow2类

...

class MainWindow : public QMainWindow
{
	...
        
private:
	...

    QPushButton *button;
    MainWindow2 w2;

    ...

// 实例方法
private slots:
    void showMainwindow2();
};
...

mainwindow.cpp:

	// 实例QPushButton控件
    button = new QPushButton(this);
    // 按钮显示位置
    button->setGeometry(QRect(50,50,100,25));
    // 按钮值
    button->setText("按钮");
    // 点击事件
    connect(button, SIGNAL(clicked()),this,SLOT(showMainwindow2()));
// 调用方法
void MainWindow::showMainwindow2(){
    // 显示MainWindow2窗体
    w2.show();
}

image-20220705142124349

字体形状窗体

	// 去掉标题栏
    this->setWindowFlag(Qt::FramelessWindowHint);
    // 设置透明背景
    this->setAttribute(Qt::WA_TranslucentBackground, true);
    // 窗体添加样式,样式为css样式表
    // background-image:url 添加图片
    // background-repeat:no-repeat 不平铺
    this->setStyleSheet("background-image:url(:/images/op.png);background-repeat:no-repeat;");

image-20220705144750830

控件应用

QPushButton 按钮

MainWindow.h:

#include <QPushButton> 
// 声明QPushButton
private:
	QPushButton *button;

// 声明QPushButton方法
private slots:
	void txtButton();

MainWindows.cpp:

	// 创建按钮
	//button = new QPushButton(QStringLiteral("按钮A"), this);
	button = new QPushButton("按钮A", this);
	// 定义按钮 X 轴,Y 轴,W 宽,H 高
	button->setGeometry(QRect(100, 100, 100, 25));
	// 给按钮添加槽事件(点击事件)
	connect(button, SIGNAL(released()), this, SLOT(txtButton()));
// 点击方法
void MainWindow::txtButton() 
{
	//  改变按钮文字
	button->setText("按钮B");
}

image-20220705185348952

QLabel 标签

MainWindow.h:

#include <QLabel>
private:
	// 声明 QLabel
	QLabel *label;

MainWindow.cpp:

	// 实例 QLabel 控件
	label = new QLabel("我是QLabel", this);
	// QLabel 位置
	// label->move(100, 100);
	label->setGeometry(QRect(100, 100, 200, 300));
	// label 样式(css 样式)
	// font-size 字号
	// color 字体颜色
	// font-weight 自宽
	// font-style 字体样式
	label->setStyleSheet("font-size:20px; color:red; font-weight:bold; font-style:italic");

image-20220705185428285

QLineEdit 单行文本

MainWindow.h:

#include <QLineEdit>
private:
	// 声明 QLineEdit 控件
	QLineEdit *lineEdit;

MainWindow.cpp:

	// 创建 QLineEdit 控件
	lineEdit = new QLineEdit(this);
	// 位置大小
	lineEdit->setGeometry(QRect(100, 100, 200, 25));
	// 样式
	// border 边框线大小
	// border-style 边框样式 solid 实线
	// border-color:blue red 上下蓝色 左右红色
	lineEdit->setStyleSheet("border:1px; border-style:solid; color:red; border-color:blue red;");
	// 限制最长输出12位
	lineEdit->setMaxLength(12);
	// 不可写入
	// lineEdit->setEchoMode(QLineEdit::NoEcho);
	// 密码*号输入
	lineEdit->setEchoMode(QLineEdit::Password);

image-20220705190013333

QTextEdit 多行文本

MainWindow.h:

#include <QTextEdit>
private:
	// 声明	QTextEdit 控件
	QTextEdit *textEdit;

MainWindow.cpp:

	// 实例
	textEdit = new QTextEdit(this);
	// 位置
	textEdit->setGeometry(QRect(50, 50, 200, 100));
	// 添加内容
	textEdit->setText("我是第一行<br/>我是第二行");

image-20220705192005151

QPlainTextEdit 多行文本

MainWindow.h:

#include <QPlainTextEdit>
private:
	// 声明 QPlainTextEdit 控件
	QPlainTextEdit *plainTextEdit;

MainWindow.cpp:

	// 实例
	plainTextEdit = new QPlainTextEdit(this);
	// 位置
	plainTextEdit->setGeometry(QRect(50, 50, 200, 150));
	// 添加内容
	plainTextEdit->setPlainText("我是第一行<br/>我是第二行");

image-20220705192629705

注:

​ QTextEdit 和 QPlainTextEdit 都为多行文本。但 QPlainTextEdit 可以理解为 QTextEdit 的低配版。QPlainTextEdit 支持纯文本显示,QTextEdit 支持富文本显示。就是多一个样式
QPlainTextEdit 显示的效率比 QTextEdit 高,如果需要显示大量文字,尤其是需要滚动条来回滚动的时候,QPlainTextEdit 要好很多。

QComboBox 下拉列表框

MainWindow.h:

#include <QComboBox>
private:	
	// 声明 QComboBox 控件
	QComboBox *comboBox;

MainWindow.cpp:

	// 实例 QComboBox
	comboBox = new QComboBox(this);
	// 控件显示位置大小
	comboBox->setGeometry(QRect(50, 50, 120, 25));
	// 定义字符串列表
	QStringList str;
	str << "数学" << "语文" << "地理";
	// 将字符串列表绑定 QComboBox 控件
	comboBox->addItems(str);

image-20220705201320968

QFontComboBox 字体下拉列表框

MainWindow.h:

#include <QFontComboBox>
#include <QPushButton>
#include <QLabel>
private:	
	// 实例控件
	QFontComboBox *fontComboBox;
	QPushButton *button;
	QLabel *fontLabel;

MainWindow.cpp:

	// 实例 QFontComboBox
	fontComboBox = new QFontComboBox(this);
	// 实例 QPushButton
	button = new QPushButton(this);
	// 实例 QLabel
	fontLabel = new QLabel(this);
	fontLabel->setGeometry(QRect(50, 150, 300, 25));
	// 按钮名
	button->setText("按钮");
	// 位置
	button->move(180, 50);
	// 事件
	connect(button, SIGNAL(released()), this, SLOT(txtFontButton()));
	// QFontComboBox 控件位置
	fontComboBox->setGeometry(QRect(50, 50, 120, 25));
// 字体下拉方法
void MainWindow::txtFontButton()
{
	fontLabel->setText("选择字体:" + fontComboBox->currentText());
}

image-20220705201127786

QSpinBox 控件

MainWindow.h:

#include <QSpinBox>
private:
	// 声明 QSpinBox 控件
	QSpinBox *spinBox;

MainWindow.cpp:

	// 实例 QSpinBox
	spinBox = new QSpinBox(this);
	// 位置
	spinBox->setGeometry(QRect(50, 50, 100, 25));
	// 值范围
	spinBox->setRange(0, 200);
	// 初始值
	spinBox->setValue(10);
	// 后缀
	spinBox->setSuffix("元");
	// 前缀
	spinBox->setPrefix("$");

image-20220706090754375

QDateEdit 日期控件

MainWindow.h:

#include <QTimeEdit>
#include <QDateTime>
private:
	// 声明 QTimeEdit 时间控件
	QTimeEdit *timeEdit;

MainWindow.cpp:

	// 实例 QTimeEdit
	timeEdit = new QTimeEdit(this);
	// 位置
	timeEdit->setGeometry(QRect(50, 50, 120, 25));
	// 获取系统时间
	QDateTime sysTime = QDateTime::currentDateTime();
	// 获取时分秒以 ':' 号拆分赋予list数组
	QStringList list = sysTime.toString("hh:mm:ss").split(':');
	// 将时分秒绑定控件 
	timeEdit->setTime(QTime(list[0].toInt(), list[1].toInt(), list[2].toInt()));

image-20220706093029353

注:

Qt获取当前时间(超详细)_世纪隐龙的博客-CSDN博客_qt 时间

QDateEdit 日期控件

MainWindow.h:

#include <QDateTime>
#include <QDateEdit>
private:
	// 声明 QDateEdit 日期控件
	QDateEdit *dateEdit;

MainWindow.cpp:

	// 实例
	dateEdit = new QDateEdit(this);
	// 位置
	dateEdit->setGeometry(QRect(50, 50, 120, 25));
	// 获取系统时间
	QDateTime sysTime = QDateTime::currentDateTime();
	// 获取时间以 '-' 号拆分赋予 list 数组
	QStringList list = sysTime.toString("yyyy-MM-dd").split('-');
	// 将年月日绑定控件
	dateEdit->setDate(QDate(list[0].toInt(), list[1].toInt(), list[2].toInt()));

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r8AoChiG-1664264171650)(…/images/image-20220706100709202.png)]

QScrollBar 控件

MainWindow.h:

#include <QScrollBar>
#include <QSpinBox>
private:
	// 实例控件
	QScrollBar *scrollBar;
	QSpinBox *spinBox;

MainWindow.cpp:

	// 实例
	scrollBar = new QScrollBar(this);
	spinBox = new QSpinBox(this);
	// 横显/竖显
	scrollBar->setOrientation(Qt::Horizontal);
	// 位置
	scrollBar->setGeometry(QRect(50, 50, 180, 20));
	spinBox->setGeometry(QRect(50, 90, 100, 25));
	// 控件条宽度
	scrollBar->setPageStep(10);
	// scrollBar 事件
	connect(scrollBar, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int)));
	// 初始值
	scrollBar->setValue(50);

image-20220706102652898

QRadioButton 单选按钮

MainWindow.h:

#include <QRadioButton>
#include <QLabel>
private:
	// 实例控件
	QRadioButton *radioM;
	QRadioButton *radioW;
	QLabel *label;
private slots:
	// 单选按钮方法
	void radioChange();

MainWindow.cpp:

	// 实例
	radioM = new QRadioButton(this);
	radioW = new QRadioButton(this);
	label = new QLabel(this);
	// 位置
	radioM->setGeometry(QRect(50, 50, 50, 50));
	radioW->setGeometry(QRect(100, 50, 50, 50));
	label->setGeometry(QRect(50, 100, 100, 25));
	radioM->setText("男");
	radioW->setText("女");
	// 默认选择
	radioM->setChecked(true);
	label->setText("男");
	// 事件
	connect(radioM, SIGNAL(clicked()), this, SLOT(radioChange()));
	connect(radioW, SIGNAL(clicked()), this, SLOT(radioChange()));
// radio 点击方法
void MainWindow::radioChange()
{
	if (sender() == radioM)
	{
		label->setText("男");
	}
	else if (sender() == radioW)
	{
		label->setText("女");
	}
}

image-20220706104707265

QCheckBox 复选框控件

MainWindow.h:

#include <QCheckBox>
#include <QLabel>
private:
	// 实例复选框控件
	QCheckBox *checkBox01;
	QCheckBox *checkBox02;
	QCheckBox *checkBox03;
	QLabel *label;
private slots:
	// 复选框方法
	void checkChange();

MainWindow.cpp:

	//实例化 checkBox 控件
	checkBox01 = new QCheckBox(this);
	checkBox02 = new QCheckBox(this);
	checkBox03 = new QCheckBox(this);
	//实例 label 控件显示结果
	label = new QLabel(this);
	//控件位置
	checkBox01->setGeometry(QRect(50, 50, 50, 50));
	checkBox02->setGeometry(QRect(100, 50, 50, 50));
	checkBox03->setGeometry(QRect(150, 50, 50, 50));
	label->setGeometry(QRect(50, 100, 200, 30));
	//控件值
	checkBox01->setText("数学");
	checkBox02->setText("语文");
	checkBox03->setText("地理");
	//checkbox 控件点击事件
	connect(checkBox01, SIGNAL(clicked(bool)), this, SLOT(checkChange()));
	connect(checkBox02, SIGNAL(clicked(bool)), this, SLOT(checkChange()));
	connect(checkBox03, SIGNAL(clicked(bool)), this, SLOT(checkChange()));
// 定义接收变量
QString str;

void MainWindow::checkChange()
{
	if (sender() == checkBox01)
	{
		// 判断是否被选中
		if (checkBox01->checkState() == Qt::Checked)
		{
			str += "数学";
		}
		else
		{
			str = str.replace(QString("数学"), QString(""));
		}
	}
	else if (sender() == checkBox02)
	{
		if (checkBox02->checkState() == Qt::Checked)
		{
			str += "语文";
		}
		else
		{
			str = str.replace(QString("语文"), QString(""));
		}
	}
	else if (sender() == checkBox03)
	{
		if (checkBox03->checkState() == Qt::Checked)
		{
			str += "地理";
		}
		else
		{
			str = str.replace(QString("地理"), QString(""));
		}
	}
	// 绑定值
	label->setText(str);
}

image-20220706105943091

QListView 列表控件

MainWindow.h:

#include <QListView> //QListView 类
#include <QStringListModel> //数据模型类
private:
	// 实例列表控件
	QListView *listView;
	QStringListModel *model;

MainWindow.cpp:

	// 实例 listView 控件
	listView = new QListView(this);
	// 定义位置宽高
	listView->setGeometry(QRect(50, 50, 100, 100));
	// StringList 数组
	QStringList string;
	string << "数学" << "语文" << "外语" << "地理";
	// 添加数据
	model = new QStringListModel(string);
	// 将数据绑定 listView 控件
	listView->setModel(model);

image-20220706112243689

QTreeView 树控件

MainWindow.h:

#include <QTreeView>
#include <QStandardItemModel>
private:
	// 实例树控件
	QTreeView *treeView;
	QStandardItemModel *model;

MainWindow.cpp:

	// 实例 QTreeView 控件
	treeView = new QTreeView(this);
	// 位置
	treeView->setGeometry(QRect(50, 50, 500, 500));
	// 实例数据类型 4 个节点,2 列
	model = new QStandardItemModel(3, 2);
	// 列名称
	model->setHeaderData(0, Qt::Horizontal, "第一列");
	model->setHeaderData(1, Qt::Horizontal, "第二列");
	// 定义节点
	QStandardItem *item1 = new QStandardItem("数学");
	item1->setIcon(QIcon(":/images/arm.png"));
	QStandardItem *item2 = new QStandardItem("语文");
	item2->setIcon(QIcon(":/images/arm.png"));
	QStandardItem *item3 = new QStandardItem("外语");
	item3->setIcon(QIcon(":/images/arm.png"));
	// 外语子项
	QStandardItem *item4 = new QStandardItem("外语 A");
	item4->setIcon(QIcon(":/images/arm.png"));
	item3->appendRow(item4);
	// 将节点添加至 QStandardItemModel
	model->setItem(0, 0, item1);
	model->setItem(1, 0, item2);
	model->setItem(2, 0, item3);
	// 将 QStandardItemModel 数据绑定 QTreeView 控件
	treeView->setModel(model);

image-20220706121739045

QTableView 表格控件

MainWindow.h:

#include <QTableView>
#include <QStandardItemModel>
private:
	// 实例表格控件
	QTableView *tableView;
	QStandardItemModel *model;

MainWindow.cpp:

	//实例
	tableView = new QTableView(this);
	//位置
	tableView->setGeometry(QRect(50, 50, 310, 200));
	//实例数据模型
	model = new QStandardItemModel();
	//定义列
	model->setHorizontalHeaderItem(0, new QStandardItem("数学"));
	model->setHorizontalHeaderItem(1, new QStandardItem("语文"));
	model->setHorizontalHeaderItem(2, new QStandardItem("外语"));
	//行数据 0 行,0 列
	model->setItem(0, 0, new QStandardItem("数学 A"));
	model->setItem(0, 1, new QStandardItem("语文 A"));
	model->setItem(0, 2, new QStandardItem("外语 A"));
	model->setItem(1, 0, new QStandardItem("数学 B"));
	model->setItem(1, 1, new QStandardItem("语文 B"));
	model->setItem(1, 2, new QStandardItem("外语 B"));
	//将数据模型绑定控件
	tableView->setModel(model);

image-20220706122453767

QHBoxLayout 横向布局

MainWindow.h:

#include <QHBoxLayout>
#include <QPushButton>
#include <QWidget>
private:
	// 定义横向布局控件
	QHBoxLayout *hboxLayout;
	QPushButton *button1;
	QPushButton *button2;
	QPushButton *button3;
	QWidget *widget;

MainWindow.cpp:

	// 创建横向布局
	hboxLayout = new QHBoxLayout();
	button1 = new QPushButton("按钮 1");
	button2 = new QPushButton("按钮 2");
	button3 = new QPushButton("按钮 3");
	// 向布局中添加控件
	hboxLayout->addWidget(button1);
	hboxLayout->addWidget(button2);
	hboxLayout->addWidget(button3);
	// 间隔
	hboxLayout->setSpacing(60);
	// 实例 QWidget
	widget = new QWidget();
	// 绑定布局
	widget->setLayout(hboxLayout);
	// 绑定界面
	this->setCentralWidget(widget);

image-20220706123010453

QGridLayout 网格布局

MainWindow.h:

#include <QGridLayout>
#include <QPushButton>
#include <QWidget>
private:
	// 定义网格布局控件
	QGridLayout *gridLayout;
	QPushButton *button1;
	QPushButton *button2;
	QPushButton *button3;
	QWidget *widget;

MainWindow.cpp:

	// 创建纵向布局
	gridLayout = new QGridLayout();
	button1 = new QPushButton("按钮 1");
	button2 = new QPushButton("按钮 2");
	button3 = new QPushButton("按钮 3");
	// 向布局中添加控件
	gridLayout->addWidget(button1, 0, 0, 1, 1);
	gridLayout->addWidget(button2, 0, 1, 1, 1);
	gridLayout->addWidget(button3, 1, 0, 1, 1);
	// 实例 QWidget
	widget = new QWidget();
	// 绑定布局
	widget->setLayout(gridLayout);
	// 绑定界面
	this->setCentralWidget(widget);

image-20220706140848786

QGroupBox 分组框控件

MainWindow.h:

#include <QGroupBox>
#include <QPushButton>
#include <QVBoxLayout>
private:
	// 实例控件
	QGroupBox *box;
	QPushButton *button;
	QVBoxLayout *vbox;

MainWindow.cpp:

	// 实例 QGroupBox
	box = new QGroupBox(this);
	// 位置、大小
	box->setGeometry(QRect(30, 30, 340, 100));
	// 标题
	box->setTitle("语音栏目");
	// 实例按钮
	button = new QPushButton();
	button->setText("按钮");
	// 实例布局
	vbox = new QVBoxLayout;
	// 将按钮加入布局
	vbox->addWidget(button);
	// 将布局加入 QGroupBox 控件
	box->setLayout(vbox);

image-20220706141626261

QTabWidget 选项卡窗口控件

MainWindow.h:

#include <QTabWidget>
#include <QWidget>
#include <QPushButton>
private:
	// 实例 QTabWidget 控件
	QTabWidget *tabWidget;
//tabA 类
class tabA :public QWidget
{
	Q_OBJECT
public:
	tabA(QWidget *parent = 0);
};

//tabB 类
class tabB :public QWidget
{
	Q_OBJECT
public:
	tabB(QWidget *parent = 0);
};

MainWindow.cpp:

	//实例 QTabWidget
	tabWidget = new QTabWidget(this);
	tabWidget->setGeometry(QRect(30, 30, 340, 140));
	tabWidget->addTab(new tabA, "A 栏目");
	tabWidget->addTab(new tabB, "B 栏目");
tabA::tabA(QWidget *parent) :QWidget(parent)
{
	QPushButton *buttonA = new QPushButton(this);
	buttonA->setText("页面 A");
}

tabB::tabB(QWidget *parent) :QWidget(parent)
{
	QPushButton *buttonB = new QPushButton(this);
	buttonB->setText("页面 B");
}

image-20220706143153636

QMenu、QToolBar 菜单栏、工具栏控件

MainWindow.h:

#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QToolBar>
#include <QMessageBox>
private:
	// 实例 QMenu QToolBar 控件
	QMenu *fileMenu, *editMenu, *helpMenu;
	QToolBar *fileToolBar, *editToolBar;
	QAction *newAct;
	QAction *cutAct;
	QAction *copyAct;
	QAction *pasteAct;
	QAction *aboutQtAct;
private slots:
	// 声明创建方法	
	void newFile();

MainWindow.cpp:

	// 实例菜单
	fileMenu = new QMenu(this);
	editMenu = new QMenu(this);
	helpMenu = new QMenu(this);
	// 填充菜单子节点
	newAct = new QAction(QIcon(":/images/new"), tr("新建"), this);
	newAct->setShortcut(tr("Ctrl+N"));
	newAct->setStatusTip(tr("新建文件"));
	connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
	cutAct = new QAction(QIcon(":/images/cut"), tr("剪切"), this);
	cutAct->setShortcut(tr("Ctrl+X"));
	cutAct->setStatusTip(tr("剪切内容"));
	copyAct = new QAction(QIcon(":/images/copy"), tr("复制"), this);
	copyAct->setShortcut(tr("Ctrl+C"));
	copyAct->setStatusTip(tr("复制内容"));
	pasteAct = new QAction(QIcon(":/images/paste"), tr("粘贴"), this);
	pasteAct->setShortcut(tr("Ctrl+V"));
	pasteAct->setStatusTip(tr("粘贴内容"));
	aboutQtAct = new QAction(tr("关于 Qt"), this);
	aboutQtAct->setStatusTip(tr("关于 Qt 信息"));
	connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
	// 填充菜单
	fileMenu = menuBar()->addMenu(tr("文件"));
	fileMenu->addAction(newAct);
	fileMenu->addSeparator(); // 分割线
	editMenu = menuBar()->addMenu(tr("编辑"));
	editMenu->addAction(cutAct);
	editMenu->addAction(copyAct);
	editMenu->addAction(pasteAct);
	menuBar()->addSeparator();
	helpMenu = menuBar()->addMenu(tr("帮助"));
	helpMenu->addAction(aboutQtAct);
	// toolBar 工具条
	fileToolBar = addToolBar(tr("新建"));
	fileToolBar->addAction(newAct);
	editToolBar = addToolBar(tr("修改"));
	editToolBar->addAction(cutAct);
	editToolBar->addAction(copyAct);
	editToolBar->addAction(pasteAct);
// 子菜单事件
void MainWindow::newFile() {
	QMessageBox::warning(this, tr("Warning"), tr("创建新文件?"), QMessageBox::Yes | QMessageBox::Default, QMessageBox::No);
}

image-20220706145239621

QSystemTrayIcon 任务栏托盘菜单

MainWindow.h:

#include <QSystemTrayIcon>//任务栏类
#include <QMenu>//菜单类
private:
	// 实例任务栏菜单控件
	QSystemTrayIcon *myTrayIcon;
	QMenu *myMenu;
	QAction *restoreWinAction;
	QAction *quitAction;
	void createMenu();
private slots:
	// 声明恢复方法
	void showNormal();

MainWindow.cpp:

	// 菜单
	createMenu();
	// 判断系统是否支持托盘图标
	if (!QSystemTrayIcon::isSystemTrayAvailable())
	{
		return;
	}
	// 实例 QSystemTrayIcon
	myTrayIcon = new QSystemTrayIcon(this);
	// 设置图标
	myTrayIcon->setIcon(QIcon(":/images/bitbug_favicon.ico"));
	// 鼠标放托盘图标上提示信息
	myTrayIcon->setToolTip("Qt 托盘图标功能");
	// 设置消息
	myTrayIcon->showMessage("托盘", "托盘管理", QSystemTrayIcon::Information, 10000);
	// 托盘菜单
	myTrayIcon->setContextMenu(myMenu);
	// 显示
	myTrayIcon->show();
// 绘制菜单
void MainWindow::createMenu()
{
	restoreWinAction = new QAction("恢复(&R)", this);
	quitAction = new QAction("退出(&Q)", this);
	// 恢复
	connect(restoreWinAction, SIGNAL(triggered()), this, SLOT(showNormal()));
	// 退出
	connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
	myMenu = new QMenu((QWidget*)QApplication::desktop());
	// 添加菜单
	myMenu->addAction(restoreWinAction);
	// 分隔符
	myMenu->addSeparator();
	myMenu->addAction(quitAction);
}

// 恢复
void MainWindow::showNormal()
{
	this->show();
}

// 点击最小化按钮隐藏界面
void QWidget::changeEvent(QEvent *e)
{
	if ((e->type() == QEvent::WindowStateChange) && this->isMinimized())
	{
		//QTimer::singleShot(100, this, SLOT(hide()));
		this->hide();
	}
}

image-20220706151205216

组件应用

日历组件

mainwindow.h:

#pragma once
#pragma execution_character_set("utf-8")

#include <QtWidgets/QMainWindow>
#include <QLabel>
#include <QLineEdit>
#include <QCalendarWidget>

#include "ui_MainWindow.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = Q_NULLPTR);

private:
    Ui::MainWindowClass ui;

	QLabel *label;
	QLineEdit *lineEdit;
	QCalendarWidget *calendarWidget;

private slots:
	void showTime();
	void setData();
};

mainwindow.cpp:

#include "MainWindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

	// 实例QLabel控件
	label = new QLabel(this);
	label->setText("选择日期:");
	// 位置
	label->setGeometry(QRect(50, 50, 100, 25));
	lineEdit = new QLineEdit(this);
	lineEdit->setGeometry(QRect(150, 50, 150, 22));
	// 事件
	connect(lineEdit, SIGNAL(cursorPositionChanged(int, int)), this, SLOT(showTime()));
	// 实例事件控件
	calendarWidget = new QCalendarWidget(this);
	// 位置
	calendarWidget->setGeometry(20, 75, 350, 180);
	// 隐藏时间控件
	calendarWidget->setHidden(true);
	// 时间控件点击事件
	connect(calendarWidget, SIGNAL(clicked(QDate)), this, SLOT(setData()));

}

void MainWindow::showTime()
{
	calendarWidget->setHidden(false);
}

void MainWindow::setData()
{
	// 选择接受时间
	QDate data = calendarWidget->selectedDate();
	// 时间格式化
	QString str = data.toString("yyyy-MM-dd");
	// 赋值
	lineEdit->setText(str);
	// 日期控件隐藏
	calendarWidget->setHidden(true);
}

image-20220706161616819

登录窗口

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include <QLabel>
#include <QGridLayout> // 纵向布局
#include <QLineEdit>
#include <QPushButton> // 按钮
#include <QHBoxLayout> // 横向布局
#include <QVBoxLayout> // 垂直布局
#include <QMessageBox> // 消息对话框

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    QLineEdit *usrLineEdit;
    QLineEdit *pwdLineEdit;
    QLabel *usrLabel;
    QLabel *pwdLabel;
    QGridLayout *gridLayout;
    QPushButton *okButton;
    QPushButton *canceButton;
    QVBoxLayout *vboxLayout;

public slots:
    virtual void accept();

};
#endif // WIDGET_H

Widget.cpp:

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    // 窗体最小宽度高度
        setMinimumSize(280, 150);
        // 窗体最大高度宽度
        setMaximumSize(280, 150);

        // 实例用户名 密码
        usrLabel = new QLabel(tr("用户名:"));
        pwdLabel = new QLabel(tr("密  码:"));
        usrLineEdit = new QLineEdit;
        pwdLineEdit = new QLineEdit;
        // 密码*号输入
        pwdLineEdit->setEchoMode(QLineEdit::Password);
        // 限制输入12位
        usrLineEdit->setMaxLength(12);
        pwdLineEdit->setMaxLength(12);

        // 实例网格布局控件
        gridLayout = new QGridLayout;

        // 添加布局 0,0,1,1 行 列 行间距 列间距
        gridLayout->addWidget(usrLabel, 0, 0, 1, 1);
        gridLayout->addWidget(usrLineEdit, 0, 1, 1, 1);

        // 间隔
        gridLayout->setSpacing(20);

        gridLayout->addWidget(pwdLabel, 1, 0, 1, 1);
        gridLayout->addWidget(pwdLineEdit, 1, 1, 1, 1);

        // 实例按钮控件
        okButton = new QPushButton(tr("确定"));
        canceButton = new QPushButton(tr("取消"));

        connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
        connect(canceButton, SIGNAL(clicked()), this, SLOT(reject()));

        QHBoxLayout *hboxLayout = new QHBoxLayout;

        hboxLayout->setSpacing(60);

        // 横向布局填充控件
        hboxLayout->addWidget(okButton);
        hboxLayout->addWidget(canceButton);

        // 实例纵向布局填充刚刚实例的两个布局
        vboxLayout = new QVBoxLayout;
        vboxLayout->addLayout(gridLayout);
        vboxLayout->addLayout(hboxLayout);

        // 显示内容
        this->setLayout(vboxLayout);
}

// 确定方法
void Widget::accept()
{
    // trimmed 去空字符
    if(usrLineEdit->text().trimmed() == "admin" && pwdLineEdit->text().trimmed() == "admin")
    {
        Widget::accept();
    }
    else
    {
        QMessageBox::warning(this,"警告","用户名或密码错误!!!", QMessageBox::Yes);
        usrLineEdit->setFocus();
    }
}


Widget::~Widget()
{
}

image-20220706181910623

文件浏览对话框

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit> // 单行文本控制类
#include <QPushButton> // 按钮类
#include <QFileDialog> // 引用文件浏览对话框

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QLineEdit *filename;
    QPushButton *button;

private slots:
    void showFiles();
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 实例单行文本控件
    filename = new QLineEdit(this);
    // 位置
    filename->setGeometry(QRect(50,50,230,25));
    // 实例按钮
    button = new QPushButton(this);
    // 按钮位置
    button->setGeometry(QRect(280,50,80,25));
    // 按钮名
    button->setText("浏览");
    // 按钮点击事件
    connect(button,SIGNAL(clicked()),this,SLOT(showFiles()));
}

// 按钮点击方法
void MainWindow::showFiles()
{
    // 定义变量str接受QFileDialog对话框获取文件路径
    QString str = QFileDialog::getOpenFileName(this,"open file","/","text file(*.txt);;C file(*.cpp);;All file(*.*)");
    // 将变量绑定QLineEdit控件
    filename->setText(str.toUtf8());
}

MainWindow::~MainWindow()
{
    delete ui;
}


image-20220706184048991

颜色选择对话框

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>
#include <QLabel>
#include <QColorDialog>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QPushButton *button;
    QLabel *label;

private slots:
    void editText();
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 实例按钮
    button = new QPushButton(this);
    // 位置
    button->setGeometry(QRect(200,50,80,25));
    // 按钮值
    button->setText("选择颜色");
    // 按钮事件
    connect(button,SIGNAL(clicked()),this,SLOT(editText()));
    // 实例QLabel
    label = new QLabel(this);
    // label 位置
    label->setGeometry(QRect(50,50,200,25));
    // label 值
    label->setText("我的颜色可以改变");
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 修改方法
void MainWindow::editText()
{
    // 颜色对话框设置
    QColorDialog::setCustomColor(0,QRgb(0xCCFFFF));
    // 定义QColor接受值
    QColor color = QColorDialog::getColor(QColor(0,250,0));
    // 定义Qpalette(调色板类)
    QPalette p = palette();
    // 调色板接受颜色
    p.setColor(QPalette::WindowText,QColor(color));
    // 给label绑定颜色
    label->setPalette(p);
}

image-20220706190937535

进度条实例

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton> // 按钮类
#include <QProgressBar> // 进度条类

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QPushButton *button;
    QProgressBar *bar;

private slots:
    void startBar();
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 实例 QProgressBar 控件
    bar = new QProgressBar(this);
    // 位置
    bar->setGeometry(QRect(50,50,200,20));
    // 范围值
    bar->setRange(0,100000-1);
    // 初始值
    bar->setValue(0);
    // 实例button
    button = new QPushButton(this);
    // 位置
    button->setGeometry(QRect(270,50,80,25));
    // 值
    button->setText("开始");
    // 事件
    connect(button,SIGNAL(clicked()),this,SLOT(startBar()));
}

void MainWindow::startBar()
{
    for(int i = 0; i < 100000; ++i)
    {
        // 100% 结束
        if(i == 99999)
        {
            button->setText("结束");
        }

        // 赋值
        bar->setValue(i);
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

image-20220706193121730

Timer实时更新时间

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <QTimer>
#include <QDateTime>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QLabel *label;
    QTimer *timer;

private slots:
    void timerTime();
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 实例 QLabel控件
    label = new QLabel(this);
    // 位置
    label->setGeometry(QRect(50,50,250,25));
    // 实例 QTimer 控件
    timer = new QTimer;
    // timer时间
    connect(timer,SIGNAL(timeout()),this,SLOT(timerTime()));
    // 执行
    timer->start(1000);
}

void MainWindow::timerTime()
{
    // 获取系统时间
    QDateTime sysTime = QDateTime::currentDateTime();
    label->setText(sysTime.toString());
}

MainWindow::~MainWindow()
{
    delete ui;
}


image-20220706194537241

文件操作

创建文件夹

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QLineEdit *edit; // 写文件路径
    QPushButton *button; // 创建路径文件按钮

private slots:
    void createFolder(); // 创建文件
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDir>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 实例QLineEdit控件
    edit = new QLineEdit(this);
    // 位置
    edit->setGeometry(QRect(50,50,250,25));
    // 值
    edit->setText("D://CreateQtLearnFolder");
    // 实例按钮
    button = new QPushButton(this);
    // 按钮位置、大小
    button->setGeometry(QRect(280,50,80,25));
    // 值
    button->setText("创建");
    // 按钮事件
    connect(button,SIGNAL(clicked()),this,SLOT(createFolder()));

}

void MainWindow::createFolder()
{
    // 实例QDir
    QDir *folder = new QDir;
    // 判断创建文件夹是否存在
    bool exist = folder->exists(edit->text());
    if(exist)
    {
        QMessageBox::warning(this,tr("创建文件夹"),tr("文件夹已存在!"));
    } else
    {
        // 创建文件夹
        bool ok = folder->mkdir(edit->text());
        // 判断是否创建成功
        if(ok)
        {
            QMessageBox::warning(this,tr("创建文件夹"),tr("文件夹创建成功!"));
        } else
        {
            QMessageBox::warning(this,tr("创建文件夹"),tr("文件夹创建失败!"));
        }

    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

image-20220720091950006

写入文件

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QPushButton *button;
    QLineEdit *edit;
    QLineEdit *content;


private slots:
    void createFile(); // 创建文件
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 实例
    edit = new QLineEdit(this);
    // 位置
    edit->setGeometry(QRect(50,50,200,25));
    // 值
    edit->setText("D:/Qt02.txt");
    // 实例
    content = new QLineEdit(this);
    // 位置
    content->setGeometry(QRect(50,100,200,25));
    // 值
    content->setText("写入文件内容");

    // 实例button
    button = new QPushButton(this);
    // 位置
    button->setGeometry(QRect(270,50,80,25));
    // 值
    button->setText("创建");
    // 事件
    connect(button,SIGNAL(clicked()),this,SLOT(createFile()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 创建文件
void MainWindow::createFile()
{
    // 实例 QFile
    QFile file(edit->text());
    // 判断文件是否存在
    if(file.exists())
    {
        QMessageBox::warning(this,"创建文件","文件已经存在!");
    }
    else
    {
        // 存在打开,不存在创建
        file.open(QIODevice::ReadWrite | QIODevice::Text);
        // 写入内容,这里需要转码,否则报错
        QByteArray str = content->text().toUtf8();
        // 写入 QByteArray 格式字符串
        file.write(str);
        // 提示成功
        QMessageBox::warning(this,"创建文件","文件创建成功!");
    }
    // 关闭文件
    file.close();
}


image-20220726191022043

修改文件内容:

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>
#include <QTextEdit>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QPushButton *browseBt;
    QPushButton *saveBt;
    QTextEdit *edit;
    QTextEdit *content;

private slots:
    // 保存文件
    void saveFile();
    // 浏览文件
    void browseFile();
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QTextStream>
#include <QTextCodec>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 文件路径
    edit = new QTextEdit(this);
    edit->setGeometry(QRect(50,50,240,26));

    // 浏览文件按钮
    browseBt = new QPushButton(this);
    browseBt->setGeometry(QRect(290,50,80,25));
    browseBt->setText("浏览文件");
    connect(browseBt,SIGNAL(clicked()),this,SLOT(browseFile()));

    // 显示文件内容
    content = new QTextEdit(this);
    content->setGeometry(QRect(50,80,320,150));

    // 修改完毕,保存文件

    saveBt = new QPushButton(this);
    saveBt->setGeometry(QRect(290,240,80,25));
    saveBt->setText("保存");
    connect(saveBt,SIGNAL(clicked()),this,SLOT(saveFile()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 保存文件
void MainWindow::saveFile()
{
    QFile file(edit->toPlainText());
    file.open(QIODevice::ReadWrite | QIODevice::Text);
    //  写入内容,这里需要转码,否则报错
    QByteArray str = content->toPlainText().toUtf8();
    // 写入QByteArray格式字符串
    file.write(str);
    // 提示成功
    QMessageBox::warning(this,"修改文件","修改文件成功!");
    file.close();
}

// 浏览文件
void MainWindow::browseFile()
{
    // 定义 str 接收 QFileDialog 对话框获取的文件路径
    QString str = QFileDialog::getOpenFileName(this,"open file","/","text file(*.txt);;C file(*.cpp);;All file(*.*)");
    // 将变量绑定QTextEdit控件
    edit->setText(str.toUtf8());
    // 判断是否选择文件
    if(edit->toPlainText().isEmpty())
    {
        return;
    }
    QFile file(edit->toPlainText());
    // 判断文件是否成功打开
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QMessageBox::warning(this,"打开文件","打开文件失败!");
        return;
    }
    QTextStream ts(&file);
    // 循环文档数据至结尾
    while (!ts.atEnd())
    {
        // 将全部数据绑定至content控件
         content->setPlainText(ts.readAll());
    }

    // 关闭文档
    file.close();
}


image-20220726200528258

删除文件

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QLineEdit *filePath;
    QPushButton *browseBt;
    QPushButton *deleteBt;

private slots:
    // 浏览文件
    void browseFile();
    // 删除文件
    void deleteFile();
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 显示文件路径
    filePath = new QLineEdit(this);
    filePath->setGeometry(QRect(50,50,200,25));

    // 浏览文件按钮
    browseBt = new QPushButton(this);
    browseBt->setText("浏览文件");
    browseBt->setGeometry(QRect(270,50,80,25));
    connect(browseBt,SIGNAL(clicked()),this,SLOT(browseFile()));

    // 删除文件按钮
    deleteBt = new QPushButton(this);
    deleteBt->setText("删除文件");
    deleteBt->setGeometry(QRect(50,100,80,25));
    connect(deleteBt,SIGNAL(clicked()),this,SLOT(deleteFile()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 浏览文件
void MainWindow::browseFile()
{
    // 定义变量str接收QFileDialog对话框获取的文件路径
    QString str = QFileDialog::getOpenFileName(this,"open file","/","text file(*.txt);;C file(*.cpp);;All file(*.*)");
    // 将变量绑定QTextEdit控件
    filePath->setText(str.toUtf8());
}

// 删除文件
void MainWindow::deleteFile()
{
    // 删除文件
    QFile::remove(filePath->text());
}


image-20220727091434921

修改文件名

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QLineEdit *filePath;
    QLineEdit *newName;
    QPushButton *browseBt;
    QPushButton *saveBt;

private slots:
    // 浏览文件
    void browseFile();
    // 删除文件
    void saveFile();
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 文件路径
    filePath = new QLineEdit(this);
    filePath->setGeometry(50,50,200,25);

    // 浏览按钮
    browseBt = new QPushButton(this);
    browseBt->setGeometry(QRect(270,50,80,25));
    browseBt->setText("浏览");
    connect(browseBt,SIGNAL(clicked()),this,SLOT(browseFile()));

    // 新名字
    newName = new QLineEdit(this);
    newName->setGeometry(QRect(50,90,200,25));
    newName->setText("新名字.txt");

    // 保存按钮
    saveBt = new QPushButton(this);
    saveBt->setGeometry(QRect(270,90,80,25));
    saveBt->setText("保存");
    connect(saveBt,SIGNAL(clicked()),this,SLOT(saveFile()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 浏览
void MainWindow::browseFile()
{
    // 定义变量str接受QFileDialog对话框获取的文件路径
    QString str = QFileDialog::getOpenFileName(this,"open file","/","text file(*.txt);;C file(*.cpp);;All file(*.*)");
    // 将变量绑定QTextEdit控件
    filePath->setText(str.toUtf8());
}

// 保存
void MainWindow::saveFile()
{
    // 实例QFileInfo函数
    QFileInfo file(filePath->text());
    // 获取文件路径
    QString path = file.absolutePath();
    // bool型变量接受是否修改成功,成功为true,不成功为false
    bool x = QFile::rename(filePath->text(), path + "/" + newName->text());
    if(x)
    {
        QMessageBox::warning(this,"修改文件名","文件修改成功!");
    } else
    {
        QMessageBox::warning(this,"修改文件名","文件修改失败!");
    }
}

image-20220801092602916

INI文件写入操作

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>
#include <QGridLayout>
#include <QWidget>
#include <QSettings>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QGridLayout *gLayout;
    QWidget *widget;
    QLabel *filePathL; // ini 文件路径Label
    QLineEdit *filePath; // ini 文件路径输入框
    QLabel *nodeL; // 节点Label
    QLineEdit *nodeEdit; // 节点输入框
    QLabel *keyL; // 键Label
    QLineEdit *keyEdit; // 键输入框
    QLabel *valL; // 值Label
    QLineEdit *valEdit;// 值输入框
    QPushButton *writeBt; // 按钮
    QSettings *writeIni;

private slots:
    void writeFile();
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // ini 文件路径Label
    filePathL = new QLabel;
    filePathL->setText("ini 文件完整路径");

    // ini 文件路径输入框
    filePath = new QLineEdit;
    filePath->setText("D:/a001.ini");

    // 节点Label
    nodeL = new QLabel;
    nodeL->setText("节点名");

    // 节点输入框
    nodeEdit = new QLineEdit;
    nodeEdit->setText("node");

    // 键Label
    keyL = new QLabel;
    keyL->setText("键值");

    // 键输入框
    keyEdit = new QLineEdit;
    keyEdit->setText("ip");

    // 值Label
    valL = new QLabel;
    valL->setText("值");

    // 值输入框
    valEdit = new QLineEdit;
    valEdit->setText("192.168.1.1");

    // 按钮
    writeBt = new QPushButton;
    writeBt->setText("写入文件");
    connect(writeBt,SIGNAL(clicked()),this,SLOT(writeFile()));

    gLayout = new QGridLayout;
    gLayout->addWidget(filePathL,0,0,1,1);
    gLayout->addWidget(filePath,0,1,1,4);
    gLayout->addWidget(nodeL,1,0,1,1);
    gLayout->addWidget(nodeEdit,1,1,1,1);
    gLayout->addWidget(keyL,2,0,1,1);
    gLayout->addWidget(keyEdit,2,1,1,1);
    gLayout->addWidget(valL,2,3,1,1);
    gLayout->addWidget(valEdit,2,4,1,1);
    gLayout->addWidget(writeBt,3,4,1,1);

    // 实例QWidget
    widget = new QWidget();
    // 绑定布局
    widget->setLayout(gLayout);
    this->setCentralWidget(widget);
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 写入文件
void MainWindow::writeFile()
{
    // QSettings 构造函数的第一个参数是ini文件的路径,第二个参数表示针对ini文件
    writeIni = new QSettings(filePath->text(),QSettings::IniFormat);
    // 写入键、值
    writeIni->setValue(nodeEdit->text() + "/" + keyEdit->text(), valEdit->text());
    // 写入完成删除指针
    delete writeIni;
}


image-20220801103517158

INI文件读取操作

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>
#include <QGridLayout>
#include <QWidget>
#include <QSettings>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QGridLayout *gLayout;
    QWidget *widget;
    QLabel *filePathL;// ini 文件路径Label
    QLineEdit *filePath;// ini 文件路径输入框
    QLabel *nodeL;// 节点Label
    QLineEdit *nodeEdit;// 节点输入框
    QLabel *keyL;// 键Label
    QLineEdit *keyEdit;// 键输入框
    QLabel *valL;// 值Label
    QLineEdit *valEdit;// 值输入框
    QPushButton *readBt;// 按钮
    QSettings *readIni;

private slots:
    void readFile();
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // ini 文件路径Label
    filePathL = new QLabel;
    filePathL->setText("ini 文件完整路径");

    // ini 文件路径输入框
    filePath = new QLineEdit;
    filePath->setText("D:/a001.ini");

    // 节点Label
    nodeL = new QLabel;
    nodeL->setText("节点名");

    // 节点输入框
    nodeEdit = new QLineEdit;
    nodeEdit->setText("node");

    // 键Label
    keyL = new QLabel;
    keyL ->setText("键值");

    // 键输入框
    keyEdit = new QLineEdit;
    keyEdit->setText("ip");

    // 值Label
    valL = new QLabel;
    valL->setText("值");

    // 值输入框
    valEdit = new QLineEdit;

    // 按钮
    readBt = new QPushButton;
    readBt->setText("读取文件");
    connect(readBt,SIGNAL(clicked()),this,SLOT(readFile()));

    gLayout = new QGridLayout;
    gLayout->addWidget(filePathL,0,0,1,1);
    gLayout->addWidget(filePath,0,1,1,4);
    gLayout->addWidget(nodeL,1,0,1,1);
    gLayout->addWidget(nodeEdit,1,1,1,1);
    gLayout->addWidget(keyL,2,0,1,1);
    gLayout->addWidget(keyEdit,2,1,1,1);
    gLayout->addWidget(valL,2,3,1,1);
    gLayout->addWidget(valEdit,2,4,1,1);
    gLayout->addWidget(readBt,3,4,1,1);

    // 实例QWidget
    widget = new QWidget();
    // 绑定布局
    widget->setLayout(gLayout);
    this->setCentralWidget(widget);
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 读取文件
void MainWindow::readFile()
{
    // QSettings构造函数的第一个参数是ini文件的路径,第二个参数表示针对ini文件
    readIni = new QSettings(filePath->text(),QSettings::IniFormat);
    // 将读取到的ini文件保存在QString中,先取值,然后通过toString()函数换成QString类型
    QString STR = nodeEdit->text() + "/" + keyEdit->text();
    QString ipResult = readIni->value(STR).toString();
    // 将结果绑定IP值控件上
    valEdit->setText(ipResult);
    // 写入完成删除指针
    delete readIni;
}


image-20220801115030656

创建XML文件

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QLabel *explainL;
    QPushButton *createBt;

private slots:
    void createFile();
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QXmlStreamWriter>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 实例QLabel
    explainL = new QLabel(this);
    explainL->setText("这里就不重复写类似txt读写布局了,直接在代码中\r\n填写节点等操作。\r\n文件路径:D:/a001.xml\r\n根节点:Root");
    explainL->setGeometry(QRect(50,50,300,100));

    // 实例按钮
    createBt = new QPushButton(this);
    createBt->setText("创建XML文件");
    createBt->setGeometry(QRect(50,180,100,25));
    connect(createBt,SIGNAL(clicked()),this,SLOT(createFile()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 创建文件
void MainWindow::createFile()
{
    // 文件路径
    QString xmlPath = "D:/a001.xml";
    QFile file(xmlPath);
    if(file.open(QIODevice::WriteOnly|QIODevice::Text))
    {
        // 实例QXmlStreamWriter
        QXmlStreamWriter stream(&file);
        stream.setAutoFormatting(true);
        // 文档头
        stream.writeStartDocument();
        // 根节点
        stream.writeStartElement("Root");
        // 元素、值
        stream.writeAttribute("href","http://qt.nokia.com/");
        // 节点内容
        stream.writeTextElement("title","Qt Home");
        stream.writeEndElement();
        stream.writeEndDocument();
        // 关闭文件
        file.close();
    }
}


image-20220801184534244

读取XML文件

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QLabel *resultL;
    QPushButton *readBt;

private slots:
    void readNode();
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QXmlStreamReader>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 实例QLabel
    resultL = new QLabel(this);
    resultL->setGeometry(QRect(50,50,300,100));

    // 实例按钮
    readBt = new QPushButton(this);
    readBt->setText("读取title节点");
    readBt->setGeometry(QRect(50,180,150,25));
    connect(readBt,SIGNAL(clicked()),this,SLOT(readNode()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 读取节点
void MainWindow::readNode()
{
    // 文件路径
    QString xmlPath = "D:/a001.xml";
    QFile file(xmlPath);

    // 定义变量接受信息
    QString str;
    // 判断文件是否存在
    if(file.exists())
    {
        if(file.open(QIODevice::ReadOnly|QIODevice::Text))
        {
            // 实例QXmlStreamReader对象读取文件
            QXmlStreamReader xmlRead(&file);

            // 循环节点
            while (!xmlRead.atEnd()) {
                // 指针下移
                xmlRead.readNext();
                if(xmlRead.isStartElement())
                {
                    // 如果节点有等于title的
                    if(xmlRead.name() == "title")
                    {
                        // 取title值赋予变量str
                        str = xmlRead.readElementText();
                    } else {
                        str = "没有找到节点";
                    }
                }
            }
            // 将值绑定QLabel控件显示
            resultL->setText(str);
        } else {
            resultL->setText("文件打开失败");
        }
        // 关闭文件
        file.close();
    }else {
        resultL->setText("文件不存在");
    }
}


image-20220801190758584

图形图像操作

绘制文字

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsScene>
#include <QGraphicsView>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 实例QGraphicsScene
    QGraphicsScene *scene = new QGraphicsScene;
    // 背景色
    scene->setForegroundBrush(QColor(0,255,255,127));
    // 字体设置
    QFont font("黑体",60);
    // 添加文字
    scene->addSimpleText("图形图像",font);
    // 网格
    // scene->setForegroundBrush(QBrush(Qt::lightGray,Qt::CrossPattern));
    // 实例QGraphicsView
    QGraphicsView *view = new QGraphicsView(scene);
    // 显示
    this->setCentralWidget(view);
}

MainWindow::~MainWindow()
{
    delete ui;
}


image-20220808094127390

绘制线条

qtLearn5PaintLine.cpp:

#include "qtLearn5PaintLine.h"

#include <QGraphicsScene>
#include <QGraphicsView>

qtLearn5PaintLine::qtLearn5PaintLine(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	// 实例QGraphicsScene
	QGraphicsScene *scene = new QGraphicsScene;

	// QPen 属性
	QPen pen;
	pen.setStyle(Qt::DashLine);// 虚线
	pen.setWidth(2);
	pen.setBrush(Qt::black);
	pen.setCapStyle(Qt::RoundCap);// 顶端是半圆形
	pen.setJoinStyle(Qt::RoundJoin);// 两条线之间有弧度,就是很圆滑

	// 绘制线条
	scene->addLine(30, 30, 200, 30, pen); // 起点的x y坐标,终点的x y坐标
	// 实例QGraphicsView
	QGraphicsView *view = new QGraphicsView(scene);
	// 显示
	this->setCentralWidget(view);
}

image-20220808131535016

绘制椭圆

qtLearn5DrawLine.cpp:

#include "qtLearn5DrawLine.h"

#include <QGraphicsScene>
#include <QGraphicsView>

qtLearn5DrawLine::qtLearn5DrawLine(QWidget* parent) : QMainWindow(parent) {
  ui.setupUi(this);

  // 实例 QGraphicsScene
  QGraphicsScene* scene = new QGraphicsScene;
  // 绘制椭圆
  scene->addEllipse(50, 50, 100, 120);  // 左上角x,y坐标,椭圆宽、高
  // 实例 QGraphicsView
  QGraphicsView* view = new QGraphicsView(scene);
  // 显示
  this->setCentralWidget(view);
}

qtLearn5DrawLine::~qtLearn5DrawLine() {}

image-20220809102252863

显示静态图像

qtLearn5ShowStaticImage.h:

#pragma once

#include <QPainter>
#include <QtWidgets/QMainWindow>

#include "ui_qtLearn5ShowStaticImage.h"

class qtLearn5ShowStaticImage : public QMainWindow {
  Q_OBJECT

 public:
  qtLearn5ShowStaticImage(QWidget *parent = nullptr);
  ~qtLearn5ShowStaticImage();

 protected:
  // paintEvent(QPaintEvent*)函数是QWidget类中的虚函数,用于ui的绘制,会在多种情况下被其他函数自动调用,比如update()时
  void paintEvent(QPaintEvent *);

 private:
  Ui::qtLearn5ShowStaticImageClass ui;
};

qtLearn5ShowStaticImage.cpp:

#include "qtLearn5ShowStaticImage.h"

qtLearn5ShowStaticImage::qtLearn5ShowStaticImage(QWidget *parent)
    : QMainWindow(parent) {
  ui.setupUi(this);
}

qtLearn5ShowStaticImage::~qtLearn5ShowStaticImage() {}

void qtLearn5ShowStaticImage::paintEvent(QPaintEvent *) {
  // 实例 QPixmap
  // 从路径的文件构造像素图。如果文件不存在或格式未知,则像素图变为空像素图
  QPixmap image(":/new/prefix/dog.png");
  // 实例 QPainter 绘制类
  QPainter painter(this);
  // 绘制图片
  painter.drawPixmap(20, 20, 200, 257, image);
}

image-20220809104854386

显示动态图像

qtLearn5ShowDynamicImage.cpp:

#include "qtLearn5ShowDynamicImage.h"

#include <QLabel>
#include <QMovie>
#include <QTimer>

qtLearn5ShowDynamicImage::qtLearn5ShowDynamicImage(QWidget *parent)
    : QMainWindow(parent) {
  ui.setupUi(this);

  // 实例 QLabel
  QLabel *label = new QLabel(this);
  label->setGeometry(QRect(50, 50, 88, 51));
  // 实例 QMovie
  QMovie *movie = new QMovie(":/new/prefix/img.gif");
  // 3 秒后图片消失
  QTimer::singleShot(3000, label, SLOT(close()));
  label->setMovie(movie);
  movie->start();
}

qtLearn5ShowDynamicImage::~qtLearn5ShowDynamicImage() {}

image-20220809111830936

image

图片水平移动

qtLearn5PictureMoveHorizontal.h:

#pragma once

#include <QImage>
#include <QLabel>
#include <QPushButton>
#include <QtWidgets/QMainWindow>

#include "ui_qtLearn5PictureMoveHorizontal.h"

class qtLearn5PictureMoveHorizontal : public QMainWindow {
  Q_OBJECT

 public:
  qtLearn5PictureMoveHorizontal(QWidget *parent = nullptr);
  ~qtLearn5PictureMoveHorizontal();

 private:
  Ui::qtLearn5PictureMoveHorizontalClass ui;

  QLabel *label;
  QImage *image;
  QPushButton *button;

 private slots:
  void moveImg();
};

qtLearn5PictureMoveHorizontal.cpp:

#include "qtLearn5PictureMoveHorizontal.h"

qtLearn5PictureMoveHorizontal::qtLearn5PictureMoveHorizontal(QWidget *parent)
    : QMainWindow(parent) {
  ui.setupUi(this);

  // 初始化 QLabel
  label = new QLabel(this);
  label->setGeometry(QRect(50, 50, 250, 150));

  // 实例 QImage
  image = new QImage;
  // QImage 加载图片
  image->load(":/new/prefix1/hd.png");
  // Label 显示图片
  label->setPixmap(QPixmap::fromImage(*image));

  // 实例 button
  button = new QPushButton(this);
  button->setGeometry(QRect(50, 250, 100, 50));
  button->setText(QString::fromLocal8Bit("移动"));
  connect(button, SIGNAL(clicked()), this, SLOT(moveImg()));
}

qtLearn5PictureMoveHorizontal::~qtLearn5PictureMoveHorizontal() {}

// 点击移动
int i = 60;
void qtLearn5PictureMoveHorizontal::moveImg() {
  // 移动 label 控件
  label->move(i, 50);
  i += 10;
}

image-20220809114708790

图片翻转

qtLearnPictureReversal.h:

#pragma once
#pragma execution_character_set("utf-8")

#include <QImage>
#include <QLabel>
#include <QPushButton>
#include <QtWidgets/QMainWindow>

#include "ui_qtLearnPictureReversal.h"

class qtLearnPictureReversal : public QMainWindow {
	Q_OBJECT

public:
	qtLearnPictureReversal(QWidget* parent = nullptr);
	~qtLearnPictureReversal();

private:
	Ui::qtLearnPictureReversalClass ui;

	QLabel* label;
	QImage* img;
	QPushButton* hBt;
	QPushButton* vBt;
	QPushButton* angleBt;

private slots:
	void hShow();
	void vShow();
	void angleShow();
};

qtLearnPictureReversal.cpp:

#include "qtLearnPictureReversal.h"

#include <QMatrix>

qtLearnPictureReversal::qtLearnPictureReversal(QWidget* parent)
	: QMainWindow(parent) {
	ui.setupUi(this);

	// 实例 QLabel
	label = new QLabel(this);
	label->setGeometry(QRect(160, 50, 2500, 150));

	// 实例 QImage
	img = new QImage;
	// Image 加载图片
	img->load(":/new/prefix/hd.png");
	// Label 显示图片
	label->setPixmap(QPixmap::fromImage(*img));

	// 实例水平操作按钮
	hBt = new QPushButton(this);
	hBt->setGeometry(QRect(50, 200, 80, 25));
	hBt->setText("水平翻转");
	connect(hBt, SIGNAL(clicked()), this, SLOT(hShow()));

	// 实例垂直操作按钮
	vBt = new QPushButton(this);
	vBt->setGeometry(QRect(160, 200, 80, 25));
	vBt->setText("垂直操作");
	connect(vBt, SIGNAL(clicked()), this, SLOT(vShow()));

	// 实例角度操作按钮 88°
	angleBt = new QPushButton(this);
	angleBt->setGeometry(QRect(270, 200, 80, 25));
	angleBt->setText("角度操作");
	connect(angleBt, SIGNAL(clicked()), this, SLOT(angleShow()));
}

qtLearnPictureReversal::~qtLearnPictureReversal() {}

// 水平操作
void qtLearnPictureReversal::hShow() {
	// 水平翻转
	*img = img->mirrored(true, false);
	// 显示图片
	label->setPixmap(QPixmap::fromImage(*img));
}


// 垂直操作
void qtLearnPictureReversal::vShow() {
	// 垂直翻转
	*img = img->mirrored(false, true);
	// 显示图片
	label->setPixmap(QPixmap::fromImage(*img));
}


// 角度操作
void qtLearnPictureReversal::angleShow() {
	QMatrix matrix;
	// 88 角度
	matrix.rotate(88);
	*img = img->transformed(matrix);
	// 显示图片
	label->setPixmap(QPixmap::fromImage(*img));
}

image-20220809155509642

图片缩放

qtLearn5PictureResize.h:

#pragma once
#pragma execution_character_set("utf-8")

#include <QtWidgets/QMainWindow>
#include "ui_qtLearn5PictureResize.h"

#include <QLabel>
#include <QImage>
#include <QPushButton>

class qtLearn5PictureResize : public QMainWindow
{
	Q_OBJECT

public:
	qtLearn5PictureResize(QWidget* parent = nullptr);
	~qtLearn5PictureResize();

private:
	Ui::qtLearn5PictureResizeClass ui;

	QLabel* label;
	QImage* img;
	QPushButton* bigBt;
	QPushButton* smallBt;

private slots:
	void bShow();
	void sShow();

};

qtLearn5PictureResize.cpp:

#include "qtLearn5PictureResize.h"

qtLearn5PictureResize::qtLearn5PictureResize(QWidget* parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	// 实例 QLabel
	label = new QLabel(this);
	label->setGeometry(QRect(160, 50, 250, 150));

	// 实例 QImage
	img = new QImage;
	// QImage 加载图片
	img->load(":/new/prefix/hd.png");
	// label 显示图片
	label->setPixmap(QPixmap::fromImage(*img));

	// 实例放大按钮
	bigBt = new QPushButton(this);
	bigBt->setGeometry(QRect(50, 200, 80, 25));
	bigBt->setText("放大");
	connect(bigBt, SIGNAL(clicked()), this, SLOT(bShow()));

	// 实例缩小按钮
	smallBt = new QPushButton(this);
	smallBt->setGeometry(QRect(260, 200, 80, 25));
	smallBt->setText("缩小");
	connect(smallBt, SIGNAL(clicked()), this, SLOT(sShow()));
}

qtLearn5PictureResize::~qtLearn5PictureResize()
{}

// 放大操作
void qtLearn5PictureResize::bShow()
{
	*img = img->scaled(100, 100, Qt::IgnoreAspectRatio);
	// 显示图片
	label->setPixmap(QPixmap::fromImage(*img));

}

// 缩小操作
void qtLearn5PictureResize::sShow()
{
	*img = img->scaled(60, 60, Qt::IgnoreAspectRatio);
	// 显示图片
	label->setPixmap(QPixmap::fromImage(*img));
}

image-20220809180010002

图片中加文字

qtLearn5PictureAddCharacter.cpp:

#include "qtLearn5PictureAddCharacter.h"

#include <QImage>
#include <QPainter>
#include <QLabel>

qtLearn5PictureAddCharacter::qtLearn5PictureAddCharacter(QWidget* parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	// 实例 QLabel
	QLabel* label = new QLabel(this);
	label->setGeometry(QRect(50, 50, 300, 250));
	//label->setText("图片已经生成,保存在项目文件中[text.jpg]。");

	// 实例 QImage
	QImage image = QPixmap(":/new/prefix/bg.png").toImage();
	// 实例 QPainter
	QPainter painter(&image);
	// 设置画刷模式
	painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
	// 改变画笔和字体
	QPen pen = painter.pen();
	pen.setColor(Qt::red);
	QFont font = painter.font();
	font.setBold(true); // 加粗
	font.setPixelSize(25); // 改变字体大小
	painter.setPen(pen);
	painter.setFont(font);
	// 将文字绘制在图片中心位置
	painter.drawText(image.rect(), Qt::AlignCenter, "你好,朋友");
	// 这个为这个图片压缩度 0/100
	int n = 100;
	// 保存图片
	image.save("text.jpg", "JPG", n);
	label->setPixmap(QPixmap::fromImage(image));
}

qtLearn5PictureAddCharacter::~qtLearn5PictureAddCharacter()
{}

image-20220809184143486

image-20220809184155508

图像扭曲

qtLearn5PictureWarp.h:

#pragma once

#include <QtWidgets/QMainWindow>
#include <QPainter>

#include "ui_qtLearn5PictureWarp.h"

class qtLearn5PictureWarp : public QMainWindow
{
    Q_OBJECT

public:
    qtLearn5PictureWarp(QWidget *parent = nullptr);
    ~qtLearn5PictureWarp();

protected:
    void paintEvent(QPaintEvent*);

private:
    Ui::qtLearn5PictureWarpClass ui;
};

qtLearn5PictureWarp.cpp:

#include "qtLearn5PictureWarp.h"

#include <QPainter>

qtLearn5PictureWarp::qtLearn5PictureWarp(QWidget* parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
}

qtLearn5PictureWarp::~qtLearn5PictureWarp()
{}

void qtLearn5PictureWarp::paintEvent(QPaintEvent*)
{
	// 实例 QPainter
	QPainter painter(this);
	// 实例 QPixmap
	QPixmap pix;
	// 加载图片
	pix.load(":/new/prefix/bg.png");
	// 原图显示
	painter.drawPixmap(0, 50, 183, 160, pix);
	// 扭曲
	painter.shear(0.5, 0); // 横向扭曲
	// 绘制扭曲图
	painter.drawPixmap(190, 50, 183, 160, pix);
}

image-20220809185851836

模糊效果

qtLearn5Blur.cpp:

#include "qtLearn5Blur.h"

#include <QLabel>
#include <QGraphicsBlurEffect>

qtLearn5Blur::qtLearn5Blur(QWidget* parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	// 实例 QLabel
	QLabel* label = new QLabel(this);
	// QLabel 位置
	label->setGeometry(QRect(50, 50, 254, 153));
	// 实例 QImage
	QImage* img = new QImage;
	// 加载图片
	img->load(":/new/prefix/yu.png");
	label->setPixmap(QPixmap::fromImage(*img));
	// 实例 QGraphicsBlurEffect
	QGraphicsBlurEffect* effrct = new QGraphicsBlurEffect(this);
	// 模糊值 值越大越模糊
	effrct->setBlurRadius(5);
	label->setGraphicsEffect(effrct);
}

qtLearn5Blur::~qtLearn5Blur()
{}

image-20220810105131032

着色效果

qtLearn5Coloration.cpp:

#include "qtLearn5Coloration.h"

#include <QLabel>
#include <QGraphicsColorizeEffect>

qtLearn5Coloration::qtLearn5Coloration(QWidget* parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	// 实例 QLabel
	QLabel* label = new QLabel(this);
	// QLabel 位置
	label->setGeometry(QRect(50, 50, 254, 153));
	// 实例 QImage
	QImage* img = new QImage;
	// 加载图片
	img->load(":/new/prefix/yu.png");
	label->setPixmap(QPixmap::fromImage(*img));
	// 实例 QGraphicsColorizeEffect
	QGraphicsColorizeEffect* effect = new QGraphicsColorizeEffect(this);
	// 设定着色
	effect->setColor(QColor(0, 0, 192));
	label->setGraphicsEffect(effect);
}

qtLearn5Coloration::~qtLearn5Coloration()
{}

image-20220810111658287

阴影效果

qtLearn5Shadows.cpp:

#include "qtLearn5Shadows.h"

#include <QLabel>
#include <QGraphicsDropShadowEffect>

qtLearn5Shadows::qtLearn5Shadows(QWidget* parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	// 实例 QLabel
	QLabel* label = new QLabel(this);
	// QLabel 位置 
	label->setGeometry(QRect(50, 50, 254, 153));
	// 实例 QImage
	QImage* img = new QImage;
	// 加载图片
	img->load(":/new/prefix/yu.png");
	label->setPixmap(QPixmap::fromImage(*img));
	// 实例 QGraphicsDropShadowEffect
	QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect(this);
	// 设定阴影
	effect->setOffset(8, 8);
	label->setGraphicsEffect(effect);
}

qtLearn5Shadows::~qtLearn5Shadows()
{}

image-20220810124021868

透明效果

qtLearn5TransparentEffect.cpp:

#include "qtLearn5TransparentEffect.h"
#include <QLabel>
#include <QGraphicsOpacityEffect>

qtLearn5TransparentEffect::qtLearn5TransparentEffect(QWidget* parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	// 实例 QLabel
	QLabel* label = new QLabel(this);
	// QLabel 位置
	label->setGeometry(QRect(50, 50, 254, 153));
	// 实例 QImage
	QImage* img = new QImage;
	// 加载图片
	img->load(":/new/prefix/yu.png");
	label->setPixmap(QPixmap::fromImage(*img));
	// 实例 QGraphicsOpacityEffect
	QGraphicsOpacityEffect* effect = new QGraphicsOpacityEffect(this);
	// 设置透明值
	effect->setOpacity(0.5);
	label->setGraphicsEffect(effect);
}

qtLearn5TransparentEffect::~qtLearn5TransparentEffect() {}

image-20220815113301110

多媒体应用

音频、视频播放器

CONFIG += qaxcontainer

HEADERS = playerwindow.h

在vs中Qt Projrct Setting的Qt Model中勾选Active Qt(Container)

image-20220815164325274

qtLearn6MovePlayer.h:

#pragma once
#pragma execution_character_set("utf-8")

#include <QAxWidget>
#include <QSlider>
#include <QToolButton>
#include <QWidget>
#include <QtWidgets/QMainWindow>

#include "ui_qtLearn6MovePlayer.h"

class qtLearn6MovePlayer : public QMainWindow {
    Q_OBJECT
  public:
    qtLearn6MovePlayer(QWidget* parent = nullptr);
    ~qtLearn6MovePlayer();

    // 播放状态 枚举类型
    enum PlayStateConstants { Stopped = 0, Paused = 1, Playing = 2 };

    enum ReadyStateConstants {
        Uninitialized = 0,
        Loading       = 1,
        Interactive   = 3,
        Complete      = 4
    };
    // Q_ENUMS() 宏的参数是枚举类型
    Q_ENUMS(ReadyStateConstants)

  protected:
    // 播放进度
    void timerEvent(QTimerEvent* event);

  private:
    Ui::qtLearn6MovePlayerClass ui;

    QAxWidget*   axWidget;         // 播放器
    QToolButton* openButton;       // 浏览按钮
    QToolButton* playPauseButton;  // 暂停播放按钮
    QToolButton* stopButton;       // 停止播放按钮
    QSlider*     seekSlider;       // 进度条
    QString      fileFilters;      // 文件格式
    int          updateTimer;      // 播放进度
    QWidget*     widget;           // QWidget

  private slots:
    void openFile();
    void onPlayStateChange(int oldState, int newState);
    void onReadyStateChange(ReadyStateConstants readyState);
    void onPositionChange(double oldPos, double newPos);
    void sliderValueChanged(int newValue);
};

qtLearn6MovePlayer.cpp:

#include "qtLearn6MovePlayer.h"

#include <QFileDialog>
#include <QHBoxLayout>
#include <QVBoxLayout>

qtLearn6MovePlayer::qtLearn6MovePlayer(QWidget* parent) : QMainWindow(parent)
{
    ui.setupUi(this);

    // 实例 QAxWidget(播放器插件)
    axWidget = new QAxWidget;

    // 注册表键值,调用插件
    /*
     * 老版本ID "22D6F312-B0F6-11D0-94AB-0080C74C7E95" (Windows Media
     * Player 6.4),向后兼容
     * 新版本ID "6BF52A52-394A-11D3-B153-00C04F79FAA6" (Windows Media Player 10)
     */
    axWidget->setControl("{22D6F312-B0F6-11D0-94AB-0080C74C7E95}");
    axWidget->setProperty("ShowControls", false);
    axWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    connect(axWidget, SIGNAL(PlayStateChange(int, int)), this,
            SLOT(onPlayStateChange(int, int)));
    connect(axWidget, SIGNAL(ReadyStateChange(ReadyStateConstants)), this,
            SLOT(onReadyStateChange(ReadyStateConstants)));
    connect(axWidget, SIGNAL(PositionChange(double, double)), this,
            SLOT(onPositionChange(double, double)));

    // 实例打开文件按钮
    openButton = new QToolButton;
    openButton->setText(tr("浏览.."));
    connect(openButton, SIGNAL(clicked()), this, SLOT(openFile()));

    // 实例播放暂停按钮
    playPauseButton = new QToolButton;
    playPauseButton->setText(tr("播放"));
    playPauseButton->setEnabled(false);  // 按钮不可点击
    connect(playPauseButton, SIGNAL(clicked()), axWidget, SLOT(Play()));

    // 停止按钮
    stopButton = new QToolButton;
    stopButton->setText(tr("停止"));
    stopButton->setEnabled(false);
    connect(stopButton, SIGNAL(clicked()), axWidget, SLOT(Stop()));

    // 进度条
    seekSlider = new QSlider(Qt::Horizontal);
    seekSlider->setEnabled(false);
    connect(seekSlider, SIGNAL(valueChange(int)), this,
            SLOT(sliderValueChanged(int)));
    connect(seekSlider, SIGNAL(sliderPressed()), axWidget, SLOT(Pause()));

    // 可播放格式 此处简写下面几个
    fileFilters = tr("Video file (*.mpg *.mpeg *.avi *.wmv *.mp4)\n"
                     "Audio files (*.mp3 *.wav)");
    // 初始化播放速度
    updateTimer = 0;

    // 三个按钮横向布局
    QHBoxLayout* buttonLayout = new QHBoxLayout;
    buttonLayout->addWidget(openButton);
    buttonLayout->addWidget(playPauseButton);
    buttonLayout->addWidget(stopButton);

    // 纵向布局 上面播放器下面三个按钮
    QVBoxLayout* mainLayout = new QVBoxLayout;
    mainLayout->addWidget(axWidget);
    mainLayout->addLayout(buttonLayout);
    mainLayout->addWidget(seekSlider);

    // 显示布局控件
    widget = new QWidget();
    widget->setLayout(mainLayout);
    this->setCentralWidget(widget);
}

qtLearn6MovePlayer::~qtLearn6MovePlayer() {}

// 进度条随播放器移动
void qtLearn6MovePlayer::timerEvent(QTimerEvent* event)
{
    if (event->timerId() == updateTimer) {
        double curPos = axWidget->property("CurrentPosition").toDouble();
        onPositionChange(-1, curPos);
    }
    else {
        QWidget::timerEvent(event);
    }
}

// 选择音频视频文件
void qtLearn6MovePlayer::openFile()
{
    // 定义 QString 变量接受文件
    QString fileName =
        QFileDialog::getOpenFileName(this, tr("Select File"), ".", fileFilters);
    // 如果文件不为空 则播放
    if (!fileName.isEmpty()) {
        axWidget->setProperty("FileName", QDir::toNativeSeparators(fileName));
    }
}

void qtLearn6MovePlayer::onPlayStateChange(int oldState, int newState)
{
    playPauseButton->disconnect(axWidget);

    switch (newState) {
        case Stopped:
            if (updateTimer) {
                killTimer(updateTimer);
                updateTimer = 0;
            }

        case Paused:
            connect(playPauseButton, SIGNAL(clicked()), axWidget, SLOT(Play()));
            stopButton->setEnabled(false);
            playPauseButton->setText(tr("播放"));
            break;

        case Playing:
            if (!updateTimer) {
                updateTimer = startTimer(100);
            }
            connect(playPauseButton, SIGNAL(clicked()), axWidget,
                    SLOT(Paused()));
            stopButton->setEnabled(true);
            playPauseButton->setText(tr("暂停"));
    }
}

void qtLearn6MovePlayer::onReadyStateChange(ReadyStateConstants readyState)
{
    if (readyState == Complete) {
        double duration = 60 * axWidget->property("DUration").toDouble();
        seekSlider->setMinimum(0);
        seekSlider->setMaximum(int(duration));
        seekSlider->setEnabled(true);
        playPauseButton->setEnabled(true);
    }
}

void qtLearn6MovePlayer::onPositionChange(double oldPos, double newPos)
{
    seekSlider->blockSignals(true);
    seekSlider->setValue(int(newPos * 60));
    seekSlider->blockSignals(false);
}

void qtLearn6MovePlayer::sliderValueChanged(int newValue)
{
    seekSlider->blockSignals(true);
    axWidget->setProperty("CurrentPosition", double(newValue) / 60);
    seekSlider->blockSignals(false);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ewJZj21X-1664264171658)(…/images/image-20220815162202829.png)]

使用 “6BF52A52-394A-11D3-B153-00C04F79FAA6” Windows Media Player 10

image-20220815162355230

播放 Flash 动画

qtLearn5FlashPlayer.cpp:

#include "qtLearn5FlashPlayer.h"

#include <QAxWidget>
#include <QDir>
#include <QVBoxLayout>
#include <QWidget>

qtLearn5FlashPlayer::qtLearn5FlashPlayer(QWidget* parent) : QMainWindow(parent)
{
    ui.setupUi(this);

    // 实例 QAxWidget
    QAxWidget* flash = new QAxWidget(0, 0);
    // 显示大小
    flash->resize(460, 370);  // 设置该空间的初始大小
    // 设置注册表键值 调用 ActiveX 插件
    flash->setControl(
        QString::fromUtf8("{d27cdb6e-ae6d-11cf-96b8-444553540000}"));
    // 设置控制器
    // 文件路径 注意如果发布可执行文件 播放文字路劲需要拷贝一份
    flash->dynamicCall("LoadMove(long,string)", 0,
                       QDir::currentPath() + "/flash/map.swf");
    // 纵向布局
    QVBoxLayout* layout = new QVBoxLayout;
    // 布局填充 QAxWidget
    layout->addWidget(flash);
    // 实例 QWidget
    QWidget* widget = new QWidget();
    widget->setLayout(layout);
    // 界面显示
    this->setCentralWidget(widget);
    // 界面标题为路劲注意查看路径
    this->setWindowTitle(QDir::currentPath());
}

qtLearn5FlashPlayer::~qtLearn5FlashPlayer() {}

flash不支持64位,且需要安装FlashActiveX插件

播放图片动画

qtLearn6ImagePlayer.h:

#pragma once

#include <QLabel>
#include <QPixmap>
#include <QTimer>
#include <QtWidgets/QMainWindow>

#include "ui_qtLearn6ImagePlayer.h"

class qtLearn6ImagePlayer : public QMainWindow {
    Q_OBJECT

  public:
    qtLearn6ImagePlayer(QWidget* parent = nullptr);
    ~qtLearn6ImagePlayer();

  private:
    Ui::qtLearn6ImagePlayerClass ui;

    QPixmap* pm;
    QLabel*  label;
    QTimer*  timer;

  private slots:
    void changeImg();
};

qtLearn6ImagePlayer.cpp:

#include "qtLearn6ImagePlayer.h"
#include <QDebug>

qtLearn6ImagePlayer::qtLearn6ImagePlayer(QWidget* parent) : QMainWindow(parent)
{
    ui.setupUi(this);

    //实例 QPixmap
    pm = new QPixmap;
    //加载第一张图片
    pm->load(":/image/a0");
    //实例 QLabel
    label = new QLabel(this);
    //位置
    label->setGeometry(QRect(50, 50, 350, 150));
    // Label 加载 QPixmap
    label->setPixmap(*pm);
    //实例 QTimer
    timer = new QTimer;
    //事件
    connect(timer, SIGNAL(timeout()), this, SLOT(changeImg()));
    //启动 QTimer
    timer->start(100);
}

qtLearn6ImagePlayer::~qtLearn6ImagePlayer() {}

//初始值
int  i = -1;
void qtLearn6ImagePlayer::changeImg()
{
    // i 不可大于 7,因为只准备了 8 张图片,i 从 0 开始。
    if (i < 7) {
        //每次 QTimer 执行 i+1;
        i++;
        //资源文件图片变量
        QString str = ":/image/a" + QString::number(i);
        //加载图片路径
        pm->load(str.toUtf8());
        // QLabel 显示图片
        label->setPixmap(*pm);
    }
    else {
        //循环一圈后,回到初始值,继续执行。
        i = -1;
    }
}

image-20220815193306616

操作系统

获取屏幕分辨率

qtLearn7ScreenResolution.cpp:

#include "qtLearn7ScreenResolution.h"

#include <QDesktopWidget>
#include <QLabel>

qtLearn7ScreenResolution::qtLearn7ScreenResolution(QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    // 实例 QLabel
    QLabel* label = new QLabel(this);
    // QLabel 位置
    label->setGeometry(QRect(50, 50, 250, 25));
    // 实例 QDesktopWidget
    QDesktopWidget* desktopWidget = QApplication::desktop();
    // 实例 QRect 接受屏幕信息
    QRect screenRect = desktopWidget->screenGeometry();
    // 定义字符串
    QString str = "屏幕分辨率为: ";
    // 屏幕宽度
    int sWidth = screenRect.width();
    // 屏幕高度
    int sHeight = screenRect.height();
    // 输出结果
    label->setText(
        str + QString::number(sWidth, 10) + " " +
        QString::number(sHeight, 10));  // QString::number 第二个参数转换进制
}

qtLearn7ScreenResolution::~qtLearn7ScreenResolution() {}

image-20220825091113244

注:

​ 用 Qt5 之前的编译版本,Qt 6.0 及之后版本,QDesktopWidget 已从 QtWidgets 模块中被彻底移除,可使用 QtGui::QScreen 代替 QtWidgets::QDesktopWidget

获取本机名、IP地址

qtLearn7GetAddressByLocalhost.cpp:

#pragma execution_character_set("utf-8")

#include "qtLearn7GetAddressByLocalhost.h"

#include <QDebug>
#include <QtNetwork/QHostInfo>

qtLearn7GetAddressByLocalhost::qtLearn7GetAddressByLocalhost(QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    // 获取计算机名称
    QString localHostName = QHostInfo::localHostName();
    qDebug() << "计算机名: " << localHostName;

    // 遍历 IP 地址
    QHostInfo info = QHostInfo::fromName(localHostName);
    // 遍历地址,只获取 IPV4 地址
    foreach (QHostAddress address, info.addresses()) {
        if (address.protocol() == QAbstractSocket::IPv4Protocol) {
            qDebug() << "ipv4地址: " << address.toString();
        }
    }
}

qtLearn7GetAddressByLocalhost::~qtLearn7GetAddressByLocalhost() {}

输出:

计算机名:  "wgq"
ipv4地址:  "192.168.1.2"

根据网址获取IP地址

qt 添加 network 模块

qtLraen7GetIPAddress.h:

#pragma once
#pragma execution_character_set("utf-8")

#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QtNetwork/QHostInfo>
#include <QtWidgets/QMainWindow>

#include "ui_qtLraen7GetIPAddress.h"

class qtLraen7GetIPAddress : public QMainWindow {
    Q_OBJECT

  public:
    qtLraen7GetIPAddress(QWidget* parent = nullptr);
    ~qtLraen7GetIPAddress();

  private:
    Ui::qtLraen7GetIPAddressClass ui;

    QLabel*      label;
    QPushButton* button;
    QLineEdit*   edit;
    QLabel*      result;

  private slots:
    void sendUrl();
    void lookedUp(const QHostInfo& host);
};

qtLraen7GetIPAddress.cpp:

#include "qtLraen7GetIPAddress.h"

#include <QtNetwork/QHostInfo>

qtLraen7GetIPAddress::qtLraen7GetIPAddress(QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    // 实例 QLabel
    label = new QLabel(this);
    label->setGeometry(QRect(50, 50, 40, 25));
    label->setText("网址: ");

    // 实例 QLineEdit
    edit = new QLineEdit(this);
    edit->setGeometry(QRect(100, 50, 150, 25));
    edit->setText("www.baidu.com");

    // 实例 QPushButton
    button = new QPushButton(this);
    button->setGeometry(QRect(260, 50, 80, 25));
    button->setText("查询");
    connect(button, SIGNAL(clicked()), this, SLOT(sendUrl()));

    // 实例 QLabel
    result = new QLabel(this);
    result->setGeometry(QRect(50, 90, 250, 25));
}

qtLraen7GetIPAddress::~qtLraen7GetIPAddress() {}

void qtLraen7GetIPAddress::sendUrl()
{
    QHostInfo::lookupHost(edit->text(), this, SLOT(lookedUp(QHostInfo)));
}

void qtLraen7GetIPAddress::lookedUp(const QHostInfo& host)
{
    result->setText("IP地址: " + host.addresses().first().toString());
}

image-20220825094404288

判断键盘按下键值

QtLearn7JudgeKey.h

#pragma once
#pragma execution_character_set("utf-8")

#include <QLabel>
#include <QtWidgets/QMainWindow>

#include "ui_QtLearn7JudgeKey.h"

class QtLearn7JudgeKey : public QMainWindow {
    Q_OBJECT

  public:
    QtLearn7JudgeKey(QWidget* parent = nullptr);
    ~QtLearn7JudgeKey();

    // 键盘事件方法
    void keyPressEvent(QKeyEvent* event);

  private:
    Ui::QtLearn7JudgeKeyClass ui;

    QLabel* label;
};

QtLearn7JudgeKey.cpp:

#include "QtLearn7JudgeKey.h"

#include <QKeyEvent>

QtLearn7JudgeKey::QtLearn7JudgeKey(QWidget* parent) : QMainWindow(parent)
{
    ui.setupUi(this);

    // 实例 QLabel
    label = new QLabel(this);
    label->setGeometry(QRect(50, 50, 200, 25));
    label->setText("按Q键改变文字");
}

QtLearn7JudgeKey::~QtLearn7JudgeKey() {}

// 键盘事件
void QtLearn7JudgeKey::keyPressEvent(QKeyEvent* event)
{
    // 键值如果等于Q
    if (event->key() == Qt::Key_Q) {
        label->setText("你按下了Q键");
    }
}

image-20220831094901105

获取系统环境变量

QtLearn7GetSystemEnvironVariables.cpp:

#pragma execution_character_set("utf-8")

#include "QtLearn7GetSystemEnvironVariables.h"

#include <QListView>
#include <QProcess>
#include <QStringListModel>

QtLearn7GetSystemEnvironVariables::QtLearn7GetSystemEnvironVariables(
    QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    // 标题
    this->setWindowTitle("获取Path环境变量");
    // 实例 QListView
    QListView* listView = new QListView(this);
    // QListView 位置
    listView->setGeometry(QRect(10, 15, 450, 350));
    // 实例 QStringList 接受 path 系统变量
    QStringList strList = QProcess::systemEnvironment();
    // 装载数据模型
    QStringListModel* model = new QStringListModel(strList);
    // 绑定数据
    listView->setModel(model);
}

QtLearn7GetSystemEnvironVariables::~QtLearn7GetSystemEnvironVariables() {}

image-20220831103701589

执行系统命令

QtLearn7RunSystemCommand.h:

#pragma once
#pragma execution_character_set("utf-8")

#include "ui_QtLearn7RunSystemCommand.h"
#include <QLabel>
#include <QLineEdit>
#include <QPlainTextEdit>
#include <QProcess>
#include <QPushButton>
#include <QtWidgets/QMainWindow>

class QtLearn7RunSystemCommand : public QMainWindow {
    Q_OBJECT

  public:
    QtLearn7RunSystemCommand(QWidget* parent = nullptr);
    ~QtLearn7RunSystemCommand();

  private:
    Ui::QtLearn7RunSystemCommandClass ui;

    QLineEdit*      comn;     // dos 命令输入框
    QPlainTextEdit* outEdit;  // 命令执行反馈框
    QPushButton*    btClick;  // 执行按钮
    QProcess*       process;  // QProcess
    QString         output;   // 接受反馈信息
    QLabel*         label;

  private slots:
    void clickExecution();  // 点击按钮事件
    void readOutput();      // QProcess 事件
};

QtLearn7RunSystemCommand.cpp:

#include "QtLearn7RunSystemCommand.h"

QtLearn7RunSystemCommand::QtLearn7RunSystemCommand(QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    // 实例命令输入框
    comn = new QLineEdit(this);
    comn->setText("ipconfig");
    comn->setGeometry(QRect(20, 20, 260, 25));

    // 实例执行按钮
    btClick = new QPushButton(this);
    btClick->setText("执行");
    btClick->setGeometry(QRect(290, 20, 80, 25));
    connect(btClick, SIGNAL(clicked()), this, SLOT(clickExecution()));

    // 实例输出对话框
    outEdit = new QPlainTextEdit(this);
    outEdit->setGeometry(QRect(20, 60, 450, 200));

    // 实例 QProcess
    process = new QProcess;
    connect(process, SIGNAL(readyRead()), this, SLOT(readOutput()));

    // dos 命令查阅
    label = new QLabel(this);
    label->setGeometry(QRect(30, 265, 200, 25));
    label->setText(tr(
        "<a href=\"http://www.baidu.com/s?wd=dos命令大全\">命令DOS查阅</a>"));
    // 开启超链接
    label->setOpenExternalLinks(true);
}

QtLearn7RunSystemCommand::~QtLearn7RunSystemCommand() {}

// 执行 DOS 命令
void QtLearn7RunSystemCommand::clickExecution()
{
    // 定义变量接受 dos 命令
    QString info = comn->text();
    // 执行命令
    process->start(info);
    // 绑定反馈值
    // outEdit->setPlainText(output);
}

// QProcess 事件
void QtLearn7RunSystemCommand::readOutput()
{
    // 接受反馈信息
    output += QString::fromLocal8Bit(process->readAll());
    // 将返回值绑定控件
    outEdit->setPlainText(output);
}

image-20220831123911372

注册表

写入注册表

QtLearn8WriteRegedit.cpp:

#pragma execution_character_set("utf-8")

#include "QtLearn8WriteRegedit.h"
#include <QSettings>

QtLearn8WriteRegedit::QtLearn8WriteRegedit(QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    // 实例 QSettings
    // 参数 1:注册表位置
    // 参数 2:操作 windows 注册表 QSettings::NativeFormat
    // 说明:QSettings::IniFormat 读写 ini 格式的配置文件
    QSettings* reg = new QSettings("HKEY_CURRENT_USER\\Software\\Qt01",
                                   QSettings::NativeFormat);

    // 设定值有修改,没有创建
    reg->setValue("键名001", "值001");
    reg->setValue("键名002", true);
    // 用完删除QSettings
    delete reg;
}

QtLearn8WriteRegedit::~QtLearn8WriteRegedit() {}

image-20220831150628481

查找注册表

QtLraen8FindRegedit.cpp:

#pragma execution_character_set("utf-8")
#include "QtLraen8FindRegedit.h"

#include <QLabel>
#include <QSettings>

QtLraen8FindRegedit::QtLraen8FindRegedit(QWidget* parent) : QMainWindow(parent)
{
    ui.setupUi(this);

    // 输出键值
    QLabel* label = new QLabel(this);
    label->setGeometry(QRect(50, 50, 200, 25));

    // 实例 QSettings
    // 参数 1:注册表在前面注册的QT001
    QSettings* reg = new QSettings("HKEY_CURRENT_USER\\Software\\Qt01",
                                   QSettings::NativeFormat);
    // 判断 value 是否为空,不为空则输出
    if (reg->value("键名001") != "") {
        QString str = reg->value("键名001").toString();
        label->setText("键名001::" + reg->value("键名001").toString());
    }
    // 删除 QSettings
    delete reg;
}

QtLraen8FindRegedit::~QtLraen8FindRegedit() {}

image-20220831170930121

修改 IE 浏览器的默认主页

想要修改注册表中软件的信息,首先需要找到该软件对应的键,例:IE键路径如下:[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main]子项,找到名称为“Start Page”的项

QtLearn8RemoveIEHome.cpp:

#include "QtLearn8RemoveIEHome.h"
#include <QSettings>

QtLearn8RemoveIEHome::QtLearn8RemoveIEHome(QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    // 实例 QSettings
    QSettings* reg = new QSettings(
        "HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Main",
        QSettings::NativeFormat);
    // 判断value是否为空,不为空则输出
    if (reg->value("Start Page") != "") {
        // IE 默认主页修改为百度
        reg->setValue("Start Page", "http://www.baidu.com");
    }
    // 删除 QSettings
    delete reg;
}

QtLearn8RemoveIEHome::~QtLearn8RemoveIEHome() {}

数据库

安装 sqlite3 并配置环境:

image-20220707165641036

在.pro工程文件加sql:

image-20220707165806058

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

private slots:
    void initDb();
    void createTable();
    void insertRecord(const QString &name, int age);
    void deleteRecord(const QString &name);
    void updateRecord(const QString &name, int age);
    int searchRecord(const QString &name);
};
#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"


#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initDb();

}

// 表的初始化
void MainWindow::initDb()
{
    qDebug()<<QSqlDatabase::drivers();//打印驱动列表
    QSqlDatabase db;
    //检测已连接的方式 - 默认连接名
    //QSqlDatabase::contains(QSqlDatabase::defaultConnection)
    if(QSqlDatabase::contains("qt_sql_default_connection"))
        db = QSqlDatabase::database("qt_sql_default_connection");
    else
        db = QSqlDatabase::addDatabase("QSQLITE");
    //检测已连接的方式 - 自定义连接名
    /*if(QSqlDatabase::contains("mysql_connection"))
        db = QSqlDatabase::database("mysql_connection");
    else
        db = QSqlDatabase::addDatabase("QSQLITE","mysql_connection");*/
    //设置数据库路径,不存在则创建
    db.setDatabaseName("sqltest.db");
    //db.setUserName("gongjianbo");  //SQLite不需要用户名和密码
    //db.setPassword("qq654344883");

    //打开数据库
    if(db.open()){
        qDebug()<<"open success";
        createTable();
        insertRecord("ww",123);
        qDebug() << searchRecord("ww");

        //关闭数据库
        db.close();
    } else {
        qDebug()<<"open error";
    }

}

// 创建表
void MainWindow::createTable(){
    //sql语句不熟悉的推荐《sql必知必会》,轻松入门
    //如果不存在则创建my_table表
    //id自增,name唯一 字符串前面加R,字符串不被转义
    const QString sql=R"(
                      CREATE TABLE IF NOT EXISTS  my_table (
                      id   INTEGER   PRIMARY KEY AUTOINCREMENT NOT NULL,
                      name CHAR (50) UNIQUE NOT NULL,
                      age  INTEGER
                      );)";
    //QSqlQuery构造前,需要db已打开并连接
    //未指定db或者db无效时使用默认连接进行操作
    QSqlQuery query;

    if(query.exec(sql)){
        qDebug()<<"init table success";
    }else{
        //打印sql语句错误信息
        qDebug()<<"init table error"<<query.lastError();
    }

}

//插入数据
void MainWindow::insertRecord(const QString &name, int age)
{
    QSqlQuery query;
    //方式一,直接执行SQL语句
    query.exec(QString(R"(INSERT INTO my_table(name,age) VALUES('%1',%2);)")
               .arg(name).arg(age));
    //方式二,绑定值,待定变量默认用问号占位,注意字符串也没有引号
    /*query.prepare(R"(INSERT INTO my_table(name,age) VALUES(?,?);)");
    query.addBindValue(name);
    query.addBindValue(age);
    query.exec();*/
}

//删除数据
void MainWindow::deleteRecord(const QString &name)
{
    QSqlQuery query;
    //方式一,直接执行SQL语句
    query.exec(QString(R"(DELETE FROM my_table WHERE name='%1';)")
               .arg(name));
    //方式二,绑定值,待定变量默认用问号占位
    /*query.prepare(R"(DELETE FROM my_table WHERE name=?;)");
    query.addBindValue(name);
    query.exec();*/
}

//更新数据
void MainWindow::updateRecord(const QString &name, int age)
{
    QSqlQuery query;
    //方式一,直接执行SQL语句
    query.exec(QString(R"(UPDATE my_table SET age=%2 WHERE name='%1';)")
               .arg(name).arg(age));
    //方式二,绑定值,待定变量默认问号,可自定义
    /*query.prepare(R"(UPDATE my_table SET age=:age WHERE name=:name;)");
    query.bindValue(":name",name);//通过自定义的别名来替代
    query.bindValue(":age",age);
    query.exec();*/
}

//查询数据
int MainWindow::searchRecord(const QString &name)
{
    QSqlQuery query;
    query.exec(QString(R"(SELECT age FROM my_table WHERE name='%1';)")
               .arg(name));

    //获取查询结果的第0个值,
    //如果结果是多行数据,可用while(query.next()){}遍历每一行
    int ageValue=-1;
    if(query.next()){
        ageValue=query.value(0).toInt();
    }
    qDebug()<<ageValue;
    return ageValue;
}

MainWindow::~MainWindow()
{
    delete ui;
}


image-20220707165933405

注:

  • lastError 输出sql错误信息
#include <QSqlError>
...
QSqlQuery query;
qDebug() << "init table error" << query.lastError();
  • 查询数据需要next、first

查询语句的结果需要next或first才能得到第一条数据,否则record停留在上一条记录

	QSqlQuery query;	
	const QString sql = R"(SELECT age FROM my_table WHERE name='%1';
    
    if(query.exec(sql.arg(name))){
    	...sqlerror
    } else {
    	if (query.next()){
    		...success...
    	} else {
    		...no select...
    	}
    }

查询数据库驱动

qtLearn9QueryDBDriver.cpp:

#include "qtLearn9QueryDBDriver.h"
#include <QDebug>
#include <QStringList>
#include <QtSql/QSqlDatabase>

qtLearn9QueryDBDriver::qtLearn9QueryDBDriver(QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    // 实例 QStringList 接收驱动信息
    QStringList drivers = QSqlDatabase::drivers();
    // 循环输出
    foreach (QString driver, drivers) {
        qDebug() << "\r" << driver;
    }
}

qtLearn9QueryDBDriver::~qtLearn9QueryDBDriver() {}

输出:

 "QSQLITE"

 "QODBC"

 "QODBC3"

 "QPSQL"

 "QPSQL7"

网络开发

TCP服务端

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QMainWindow>
#include <QMessageBox>
#include <QMetaType>
#include <QSet>
#include <QStandardPaths>
#include <QTcpServer>
#include <QTcpSocket>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow {
    Q_OBJECT

  public:
    explicit MainWindow(QWidget* parent = nullptr);
    ~MainWindow();

  signals:
    void newMessage(QString);
  private slots:
    void newConnection();
    void appendToSocketList(QTcpSocket* socket);

    void readSocket();
    void discardSocket();
    void displayError(QAbstractSocket::SocketError socketError);

    void displayMessage(const QString& str);
    void sendMessage(QTcpSocket* socket);
    void sendAttachment(QTcpSocket* socket, QString filePath);

    void on_pushButton_sendMessage_clicked();
    void on_pushButton_sendAttachment_clicked();

    void refreshComboBox();

  private:
    Ui::MainWindow* ui;

    QTcpServer*       m_server;        // 服务器指针
    QSet<QTcpSocket*> connection_set;  // 客户端连接列表
};

#endif  // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_server = new QTcpServer();

    // 监听
    if (m_server->listen(QHostAddress::Any, 8080)) {
        connect(this, &MainWindow::newMessage, this,
                &MainWindow::displayMessage);  // 监听消息
        connect(m_server, &QTcpServer::newConnection, this,
                &MainWindow::newConnection);  // 监听连接
        ui->statusBar->showMessage("Server is listening...");
    }
    else {
        QMessageBox::critical(this, "QTCPServer",
                              QString("Unable to start the server: %1.")
                                  .arg(m_server->errorString()));
        exit(EXIT_FAILURE);
    }
}

MainWindow::~MainWindow()
{
    foreach (QTcpSocket* socket, connection_set) {
        socket->close();
        socket->deleteLater();
    }

    m_server->close();
    m_server->deleteLater();

    delete ui;
}

// 客户端建立新连接
void MainWindow::newConnection()
{
    while (m_server->hasPendingConnections())
        appendToSocketList(m_server->nextPendingConnection());
}

// 新客户端绑定服务器连接
void MainWindow::appendToSocketList(QTcpSocket* socket)
{
    connection_set.insert(socket);
    connect(socket, &QTcpSocket::readyRead, this, &MainWindow::readSocket);
    connect(socket, &QTcpSocket::disconnected, this,
            &MainWindow::discardSocket);
    connect(socket, &QAbstractSocket::errorOccurred, this,
            &MainWindow::displayError);
    ui->comboBox_receiver->addItem(QString::number(socket->socketDescriptor()));
    displayMessage(
        QString("INFO :: Client with sockd:%1 has just entered the room")
            .arg(socket->socketDescriptor()));
}

// 读取传过来的数据
void MainWindow::readSocket()
{
    QTcpSocket* socket = reinterpret_cast<QTcpSocket*>(sender());

    QByteArray buffer;

    QDataStream socketStream(socket);
    // 当操作复杂数据类型时,我们就要确保读取和写入时的QDataStream版本是一样的
    // 如果你需要向前和向后兼容,可以在代码中使用硬编码指定流的版本号
    socketStream.setVersion(QDataStream::Qt_5_15);

    socketStream.startTransaction();
    socketStream >> buffer;  // 获取数据流的头

    if (!socketStream.commitTransaction()) {
        QString message = QString("%1 :: Waiting for more data to come..")
                              .arg(socket->socketDescriptor());
        emit newMessage(message);
        return;
    }

    // 拆分头判断数据类型
    QString header   = buffer.mid(0, 128);
    QString fileType = header.split(",")[0].split(":")[1];

    buffer = buffer.mid(128);

    if (fileType == "attachment") {
        QString fileName = header.split(",")[1].split(":")[1];
        QString ext      = fileName.split(".")[1];
        QString size     = header.split(",")[2].split(":")[1].split(";")[0];

        if (QMessageBox::Yes ==
            QMessageBox::question(
                this, "QTCPServer",
                QString("You are receiving an attachment from sd:%1 of size: "
                        "%2 bytes, called %3. Do you want to accept it?")
                    .arg(socket->socketDescriptor())
                    .arg(size)
                    .arg(fileName))) {
            QString filePath = QFileDialog::getSaveFileName(
                this, tr("Save File"),
                QStandardPaths::writableLocation(
                    QStandardPaths::DocumentsLocation) +
                    "/" + fileName,
                QString("File (*.%1)").arg(ext));

            QFile file(filePath);
            if (file.open(QIODevice::WriteOnly)) {
                file.write(buffer);
                QString message =
                    QString("INFO :: Attachment from sd:%1 successfully stored "
                            "on disk under the path %2")
                        .arg(socket->socketDescriptor())
                        .arg(QString(filePath));
                emit newMessage(message);
            }
            else
                QMessageBox::critical(
                    this, "QTCPServer",
                    "An error occurred while trying to write the attachment.");
        }
        else {
            QString message = QString("INFO :: Attachment from sd:%1 discarded")
                                  .arg(socket->socketDescriptor());
            emit newMessage(message);
        }
    }
    else if (fileType == "message") {
        QString message =
            QString("%1 :: %2")
                .arg(socket->socketDescriptor())
                .arg(QString::fromStdString(buffer.toStdString()));
        emit newMessage(message);
    }
}

// 客户端断开连接
void MainWindow::discardSocket()
{
    QTcpSocket* socket             = reinterpret_cast<QTcpSocket*>(sender());
    QSet<QTcpSocket*>::iterator it = connection_set.find(socket);
    if (it != connection_set.end()) {
        displayMessage(QString("INFO :: A client has just left the room")
                           .arg(socket->socketDescriptor()));
        connection_set.remove(*it);
    }
    refreshComboBox();

    socket->deleteLater();
}

// 处理异常 错误弹窗
void MainWindow::displayError(QAbstractSocket::SocketError socketError)
{
    switch (socketError) {
        case QAbstractSocket::RemoteHostClosedError: break;
        case QAbstractSocket::HostNotFoundError:
            QMessageBox::information(this, "QTCPServer",
                                     "The host was not found. Please check the "
                                     "host name and port settings.");
            break;
        case QAbstractSocket::ConnectionRefusedError:
            QMessageBox::information(
                this, "QTCPServer",
                "The connection was refused by the peer. Make sure QTCPServer "
                "is running, and check that the host name and port settings "
                "are correct.");
            break;
        default:
            QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
            QMessageBox::information(
                this, "QTCPServer",
                QString("The following error occurred: %1.")
                    .arg(socket->errorString()));
            break;
    }
}

// 服务器发送消息
void MainWindow::on_pushButton_sendMessage_clicked()
{
    QString receiver = ui->comboBox_receiver->currentText();

    // 发送给所有客户端
    if (receiver == "Broadcast") {
        foreach (QTcpSocket* socket, connection_set) {
            sendMessage(socket);
        }
    }
    //发送给指定客户端
    else {
        foreach (QTcpSocket* socket, connection_set) {
            if (socket->socketDescriptor() == receiver.toLongLong()) {
                sendMessage(socket);
                break;
            }
        }
    }
    ui->lineEdit_message->clear();
}

// 服务器发送文件
void MainWindow::on_pushButton_sendAttachment_clicked()
{
    QString receiver = ui->comboBox_receiver->currentText();

    QString filePath = QFileDialog::getOpenFileName(
        this, ("Select an attachment"),
        QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
        ("File (*.json *.txt *.png *.jpg *.jpeg)"));

    if (filePath.isEmpty()) {
        QMessageBox::critical(this, "QTCPClient",
                              "You haven't selected any attachment!");
        return;
    }

    // 发送给所有客户端
    if (receiver == "Broadcast") {
        foreach (QTcpSocket* socket, connection_set) {
            sendAttachment(socket, filePath);
        }
    }
    // 发送给指定客户端
    else {
        foreach (QTcpSocket* socket, connection_set) {
            if (socket->socketDescriptor() == receiver.toLongLong()) {
                sendAttachment(socket, filePath);
                break;
            }
        }
    }
    ui->lineEdit_message->clear();
}

// 发送消息
void MainWindow::sendMessage(QTcpSocket* socket)
{
    if (socket) {
        if (socket->isOpen()) {
            QString str = ui->lineEdit_message->text();

            QDataStream socketStream(socket);
            socketStream.setVersion(QDataStream::Qt_5_15);

            QByteArray header;
            header.prepend(
                QString("fileType:message,fileName:null,fileSize:%1;")
                    .arg(str.size())
                    .toUtf8());
            header.resize(128);

            QByteArray byteArray = str.toUtf8();
            byteArray.prepend(header);

            socketStream << byteArray;
        }
        else
            QMessageBox::critical(this, "QTCPServer",
                                  "Socket doesn't seem to be opened");
    }
    else
        QMessageBox::critical(this, "QTCPServer", "Not connected");
}

// 发送文件
void MainWindow::sendAttachment(QTcpSocket* socket, QString filePath)
{
    if (socket) {
        if (socket->isOpen()) {
            QFile m_file(filePath);
            if (m_file.open(QIODevice::ReadOnly)) {
                QFileInfo fileInfo(m_file.fileName());
                QString   fileName(fileInfo.fileName());

                QDataStream socketStream(socket);
                socketStream.setVersion(QDataStream::Qt_5_15);

                QByteArray header;
                header.prepend(
                    QString("fileType:attachment,fileName:%1,fileSize:%2;")
                        .arg(fileName)
                        .arg(m_file.size())
                        .toUtf8());
                header.resize(128);

                QByteArray byteArray = m_file.readAll();
                byteArray.prepend(header);

                socketStream << byteArray;
            }
            else
                QMessageBox::critical(this, "QTCPClient",
                                      "Couldn't open the attachment!");
        }
        else
            QMessageBox::critical(this, "QTCPServer",
                                  "Socket doesn't seem to be opened");
    }
    else
        QMessageBox::critical(this, "QTCPServer", "Not connected");
}

// 消息展示
void MainWindow::displayMessage(const QString& str)
{
    ui->textBrowser_receivedMessages->append(str);
}

// 客户端断开后删除combobox中ip连接
void MainWindow::refreshComboBox()
{
    ui->comboBox_receiver->clear();
    ui->comboBox_receiver->addItem("Broadcast");
    foreach (QTcpSocket* socket, connection_set)
        ui->comboBox_receiver->addItem(
            QString::number(socket->socketDescriptor()));
}

image-20220902194542715

TCP客户端

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QAbstractSocket>
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QHostAddress>
#include <QMessageBox>
#include <QMetaType>
#include <QString>
#include <QStandardPaths>
#include <QTcpSocket>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
signals:
    void newMessage(QString);
private slots:
    void readSocket();
    void discardSocket();
    void displayError(QAbstractSocket::SocketError socketError);

    void displayMessage(const QString& str);
    void on_pushButton_sendMessage_clicked();
    void on_pushButton_sendAttachment_clicked();
private:
    Ui::MainWindow *ui;

    QTcpSocket* socket;
};

#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    socket = new QTcpSocket(this);

    connect(this, &MainWindow::newMessage, this,
            &MainWindow::displayMessage);  // 展示消息
    connect(socket, &QTcpSocket::readyRead, this,
            &MainWindow::readSocket);  // 建立连接,读取消息
    connect(socket, &QTcpSocket::disconnected, this,
            &MainWindow::discardSocket);  // 没有成功建立连接
    connect(socket, &QAbstractSocket::errorOccurred, this,
            &MainWindow::displayError);  // 错误异常

    socket->connectToHost(QHostAddress::LocalHost, 8080);

    if (socket->waitForConnected())
        ui->statusBar->showMessage("Connected to Server");
    else {
        QMessageBox::critical(this, "QTCPClient",
                              QString("The following error occurred: %1.")
                                  .arg(socket->errorString()));
        exit(EXIT_FAILURE);
    }
}

MainWindow::~MainWindow()
{
    if (socket->isOpen())
        socket->close();
    delete ui;
}

// 读取消息
void MainWindow::readSocket()
{
    QByteArray buffer;

    QDataStream socketStream(socket);
    socketStream.setVersion(QDataStream::Qt_5_15);

    socketStream.startTransaction();
    socketStream >> buffer;

    if (!socketStream.commitTransaction()) {
        QString message = QString("%1 :: Waiting for more data to come..")
                              .arg(socket->socketDescriptor());
        emit newMessage(message);
        return;
    }

    // mid
    // 从位置pos开始,从该字节数组返回一个包含len个字节的字节数组。
    // 如果len为-1(默认值),或者pos+ len> =size(),
    // 则返回一个字节数组,其中包含从位置pos到字节数组末尾的所有字节
    QString header   = buffer.mid(0, 128);
    QString fileType = header.split(",")[0].split(":")[1];

    buffer = buffer.mid(128);

    // 读取文件
    if (fileType == "attachment") {
        QString fileName = header.split(",")[1].split(":")[1];
        QString ext      = fileName.split(".")[1];
        QString size     = header.split(",")[2].split(":")[1].split(";")[0];

        if (QMessageBox::Yes ==
            QMessageBox::question(
                this, "QTCPServer",
                QString("You are receiving an attachment from sd:%1 of size: "
                        "%2 bytes, called %3. Do you want to accept it?")
                    .arg(socket->socketDescriptor())
                    .arg(size)
                    .arg(fileName))) {
            QString filePath = QFileDialog::getSaveFileName(
                this, tr("Save File"),
                QStandardPaths::writableLocation(
                    QStandardPaths::DocumentsLocation) +
                    "/" + fileName,
                QString("File (*.%1)").arg(ext));

            QFile file(filePath);
            if (file.open(QIODevice::WriteOnly)) {
                file.write(buffer);
                QString message =
                    QString("INFO :: Attachment from sd:%1 successfully stored "
                            "on disk under the path %2")
                        .arg(socket->socketDescriptor())
                        .arg(QString(filePath));
                emit newMessage(message);
            }
            else
                QMessageBox::critical(
                    this, "QTCPServer",
                    "An error occurred while trying to write the attachment.");
        }
        else {
            QString message = QString("INFO :: Attachment from sd:%1 discarded")
                                  .arg(socket->socketDescriptor());
            emit newMessage(message);
        }
    }
    // 读取消息
    else if (fileType == "message") {
        QString message =
            QString("%1 :: %2")
                .arg(socket->socketDescriptor())
                .arg(QString::fromStdString(buffer.toStdString()));
        emit newMessage(message);
    }
}

// 没有成功连接服务器
void MainWindow::discardSocket()
{
    socket->deleteLater();
    socket = nullptr;

    ui->statusBar->showMessage("Disconnected!");
}

// 错误异常
void MainWindow::displayError(QAbstractSocket::SocketError socketError)
{
    switch (socketError) {
        case QAbstractSocket::RemoteHostClosedError: break;
        case QAbstractSocket::HostNotFoundError:
            QMessageBox::information(this, "QTCPClient",
                                     "The host was not found. Please check the "
                                     "host name and port settings.");
            break;
        case QAbstractSocket::ConnectionRefusedError:
            QMessageBox::information(
                this, "QTCPClient",
                "The connection was refused by the peer. Make sure QTCPServer "
                "is running, and check that the host name and port settings "
                "are correct.");
            break;
        default:
            QMessageBox::information(
                this, "QTCPClient",
                QString("The following error occurred: %1.")
                    .arg(socket->errorString()));
            break;
    }
}

// 发送消息
void MainWindow::on_pushButton_sendMessage_clicked()
{
    if (socket) {
        if (socket->isOpen()) {
            QString str = ui->lineEdit_message->text();

            QDataStream socketStream(socket);
            socketStream.setVersion(QDataStream::Qt_5_15);

            QByteArray header;
            header.prepend(
                QString("fileType:message,fileName:null,fileSize:%1;")
                    .arg(str.size())
                    .toUtf8());
            header.resize(128);

            QByteArray byteArray = str.toUtf8();
            byteArray.prepend(header);

            socketStream << byteArray;

            ui->lineEdit_message->clear();
        }
        else
            QMessageBox::critical(this, "QTCPClient",
                                  "Socket doesn't seem to be opened");
    }
    else
        QMessageBox::critical(this, "QTCPClient", "Not connected");
}

// 发送文件
void MainWindow::on_pushButton_sendAttachment_clicked()
{
    if (socket) {
        if (socket->isOpen()) {
            QString filePath = QFileDialog::getOpenFileName(
                this, ("Select an attachment"),
                QStandardPaths::writableLocation(
                    QStandardPaths::DocumentsLocation),
                ("File (*.json *.txt *.png *.jpg *.jpeg)"));

            if (filePath.isEmpty()) {
                QMessageBox::critical(this, "QTCPClient",
                                      "You haven't selected any attachment!");
                return;
            }

            QFile m_file(filePath);
            if (m_file.open(QIODevice::ReadOnly)) {
                QFileInfo fileInfo(m_file.fileName());
                QString   fileName(fileInfo.fileName());

                QDataStream socketStream(socket);
                socketStream.setVersion(QDataStream::Qt_5_15);

                QByteArray header;
                // prepend 前置
                header.prepend(
                    QString("fileType:attachment,fileName:%1,fileSize:%2;")
                        .arg(fileName)
                        .arg(m_file.size())
                        .toUtf8());
                header.resize(128);

                QByteArray byteArray = m_file.readAll();
                byteArray.prepend(header);

                socketStream << byteArray;
            }
            else
                QMessageBox::critical(this, "QTCPClient",
                                      "Attachment is not readable!");
        }
        else
            QMessageBox::critical(this, "QTCPClient",
                                  "Socket doesn't seem to be opened");
    }
    else
        QMessageBox::critical(this, "QTCPClient", "Not connected");
}

// 展示消息
void MainWindow::displayMessage(const QString& str)
{
    ui->textBrowser_receivedMessages->append(str);
}

image-20220902194643845

线程与进程

线程管理器

qtLearn11ProcessManager.h:

#pragma once
#pragma execution_character_set("utf-8")

#include "ui_qtLearn11ProcessManager.h"
#include <QStandardItemModel>
#include <QTableView>
#include <QtWidgets/QMainWindow>

class qtLearn11ProcessManager : public QMainWindow {
    Q_OBJECT

  public:
    qtLearn11ProcessManager(QWidget* parent = nullptr);
    ~qtLearn11ProcessManager();

  private:
    Ui::qtLearn11ProcessManagerClass ui;

    QTableView*         tableView;
    QStandardItemModel* model;
    QString             cPid;

  private slots:
    // QTableView 行事件
    void sendContent(QModelIndex);
    //点击删除事件
    void deletePro();
};

qtLearn11ProcessManager.cpp:

#include "qtLearn11ProcessManager.h"
#include "windows.h"   //1 顺序不可颠倒
#include "tlhelp32.h"  //2
#include <QDebug>
#include <QHeaderView>
#include <QMessageBox>
#include <QProcess>
#include <QPushButton>

qtLearn11ProcessManager::qtLearn11ProcessManager(QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    //实例 QListView
    tableView = new QTableView(this);
    // QListView 位置
    tableView->setGeometry(QRect(10, 10, 340, 430));
    //实例 QPushButton
    QPushButton* button = new QPushButton(this);
    button->setGeometry(QRect(500, 450, 80, 25));
    button->setText("结束进程");
    connect(button, SIGNAL(clicked()), this, SLOT(deletePro()));
    //实例数据模型
    model = new QStandardItemModel();
    model->setHorizontalHeaderItem(0, new QStandardItem("进程名"));
    model->setHorizontalHeaderItem(1, new QStandardItem("PID"));
    //获取系统快照句柄,可以获取进程、线程、模块、进程使用的堆的句柄
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == FALSE) {
        qDebug() << "调用失败";
        return;
    }
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    BOOL bRet   = Process32First(hProcessSnap, &pe32);
    int  i      = 0;
    while (bRet) {
        // i++;
        前面 2 行不要
        // if (i > 1) {
        //     //获取进程名
        //     QString pName = QString::fromWCharArray(pe32.szExeFile);
        //     //追加数据模型第一列
        //     model->setItem(i - 2, 0, new QStandardItem(pName));
        //     //获取 PID 号
        //     QString pid = QString::number(pe32.th32ProcessID);
        //     //追加数据模型第二列
        //     model->setItem(i - 2, 1, new QStandardItem(pid));
        // }

        //获取进程名
        QString pName = QString::fromWCharArray(pe32.szExeFile);
        //追加数据模型第一列
        model->setItem(i - 2, 0, new QStandardItem(pName));
        //获取 PID 号
        QString pid = QString::number(pe32.th32ProcessID);
        //追加数据模型第二列
        model->setItem(i - 2, 1, new QStandardItem(pid));

        bRet = Process32Next(hProcessSnap, &pe32);
        i++;
    }
    //清理 hProcessSnap
    ::CloseHandle(hProcessSnap);

    //绑定数据
    tableView->setModel(model);
    //列宽
    tableView->setColumnWidth(0, 190);
    tableView->setColumnWidth(1, 130);
    //选取整行
    tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    //不可修改
    tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    //行单击事件
    connect(tableView, SIGNAL(clicked(QModelIndex)),
            SLOT(sendContent(QModelIndex)));
    //纵向头隐藏
    tableView->verticalHeader()->setVisible(false);
    //关闭滚动条
    // tableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    //隔行变色
    tableView->setAlternatingRowColors(true);
}

qtLearn11ProcessManager::~qtLearn11ProcessManager() {}

// QTableView 点击行事件
void qtLearn11ProcessManager::sendContent(QModelIndex)
{
    //获取点击行索引
    int index = tableView->currentIndex().row();
    //将 PID 值赋予 QString 类型保存
    cPid = model->data(model->index(index, 1)).toString();
}
//点击结束进程
void qtLearn11ProcessManager::deletePro()
{
    if (cPid == "") {
        QMessageBox::warning(this, "警告", tr("请选择要结束的进程!!!"));
    }
    else {
        // Taskkill/pid 3184
        //结束进程命令
        QProcess    process(0);
        QString     dos = "Taskkill";
        QStringList list;
        list.append("/pid");
        list.append(cPid);
        //拼接参数,因为 QProcess 不支持中文与空格
        process.start(dos, list);
        QMessageBox::warning(this, "警告", tr("成功结束!!!"));
    }
}

image-20220926094050620

线程 QThread 应用

qtLearn11QThread.h:

#pragma once
#pragma execution_character_set("utf-8")

#include "ui_qtLearn11QThread.h"
#include <QPushButton>
#include <QThread>
#include <QtWidgets/QMainWindow>

class qtLearn11QThread : public QMainWindow {
    Q_OBJECT

  public:
    qtLearn11QThread(QWidget* parent = nullptr);
    ~qtLearn11QThread();

  private:
    Ui::qtLearn11QThreadClass ui;
    QPushButton*              starThread;
    QThread*                  thread;

  private slots:
    //执行线程
    void startFun();
};

qtLearn11QThread.cpp:

#include "qtLearn11QThread.h"
#include <QDebug>

qtLearn11QThread::qtLearn11QThread(QWidget* parent) : QMainWindow(parent)
{
    ui.setupUi(this);

    //执行线程 1
    starThread = new QPushButton(this);
    starThread->setText("执行线程 1");
    starThread->setGeometry(QRect(30, 50, 100, 25));
    connect(starThread, SIGNAL(clicked()), this, SLOT(startFun()));
}

qtLearn11QThread::~qtLearn11QThread() {}

void qtLearn11QThread::startFun()
{
    //实例线程
    thread = new QThread();
    //启动
    thread->start();
    int i = 0;
    while (true) {
        //挂起 1 秒
        thread->sleep(1);
        i++;
        qDebug() << i;
        if (i > 2) {
            break;
        }
    }
    qDebug() << "结束";
}

image-20220926093956540

线程 QRunnable 应用

runnable.h:

#include <QProgressBar>
#include <QRunnable>
class runnable : public QRunnable {
  public:
    runnable(QProgressBar* progressBar);
    virtual ~runnable();
    void run();

  private:
    QProgressBar* m_ProgressBar;
};

runnable.cpp:

#include "runnable.h"
#include <QProgressBar>
runnable::runnable(QProgressBar* progressBar)
    : QRunnable(), m_ProgressBar(progressBar)
{
    for (int i = 0; i < 100000; i++) {
        progressBar->setValue(i);
    }
}
runnable::~runnable() {}

void runnable::run(){}

qtLearn11QRunnable.h:

#pragma once
#pragma execution_character_set("utf-8")

#include "ui_qtLearn11QRunnable.h"
#include <QProgressBar>
#include <QPushButton>
#include <QtWidgets/QMainWindow>

class qtLearn11QRunnable : public QMainWindow {
    Q_OBJECT

  public:
    qtLearn11QRunnable(QWidget* parent = nullptr);
    ~qtLearn11QRunnable();

  private:
    Ui::qtLearn11QRunnableClass ui;

    QPushButton*  startButton;
    QProgressBar* progressBar;
    QProgressBar* progressBar2;
  private slots:
    void startFun();
};

qtLearn11QRunnable.cpp:

#include "qtLearn11QRunnable.h"
#include "runnable.h"
#include <QProgressBar>
#include <QThreadPool>

qtLearn11QRunnable::qtLearn11QRunnable(QWidget* parent) : QMainWindow(parent)
{
    ui.setupUi(this);

    //第一个 QProgressBar
    progressBar = new QProgressBar(this);
    progressBar->setGeometry(QRect(50, 50, 200, 16));
    //初始值
    progressBar->setValue(0);
    //范围值
    progressBar->setRange(0, 100000 - 1);
    //第二个 QProgressBar
    progressBar2 = new QProgressBar(this);
    progressBar2->setGeometry(QRect(50, 100, 200, 16));
    //初始值
    progressBar2->setValue(0);
    //范围值
    progressBar2->setRange(0, 100000 - 1);
    //实例按钮
    startButton = new QPushButton(this);
    startButton->setGeometry(QRect(260, 45, 80, 25));
    startButton->setText("执行");
    connect(startButton, SIGNAL(clicked()), this, SLOT(startFun()));
}

qtLearn11QRunnable::~qtLearn11QRunnable() {}

//开始执行
void qtLearn11QRunnable::startFun()
{
    //实例 runnable 类
    runnable* hInst = new runnable(progressBar);
    //实例第二个
    hInst = new runnable(progressBar2);
    //进程池
    QThreadPool::globalInstance()->start(hInst);
}

image-20220926100148802

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王小白学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值