主窗体、QFile、编码转换、事件、禁止输入特殊字符

主窗体

部件构成

菜单栏、工具栏、主窗体、状态栏。

UI 编辑器设计主窗体

在这里插入图片描述

💡 简易记事本的实现(part 1)

在这里插入图片描述

菜单栏

在这里插入图片描述
在这里插入图片描述

工具栏(图标)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

主窗体

在这里插入图片描述

完善菜单栏:
在这里插入图片描述

mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);this->setWindowTitle("新建文本文档 - txt");this->setWindowIcon(QIcon("://notepad.png"));
}MainWindow::~MainWindow()
{delete ui;
}

Functions

状态栏显示提示信息

设置显示的时长,时间单位:ms。

void showMessage(const QString & message, int timeout = 0);

设置标题栏的标题、图标

void setWindowTitle(const QString &);  			// 设置标题栏的标题
void setWindowIcon(const QIcon & icon);  		// 设置标题栏的图标

设置图标然后运行,如果不能正常显示,不用理会,是系统的问题。

QFile

继承关系

QObject – QIODevice – QFileDevice – QFile
QIODevice:QT 对输入输出设备的抽象,提供了操作设备的一系列接口。

接口

QFile(const QString &name);  	// 使用文件名构造一个 QFile 对象,文件名可以包含路径和文件名void	setFileName(const QString & name);  // 如果构造没指定,也可以通过这个接口指定一下
bool	exists(); 							// 判断文件是否存在
bool 	open(OpenMode mode); 				// 继承自 QIODevice,OpenMode 取值:QIODevice::ReadOnlyQIODevice::WriteOnlyQIODevice::ReadWrite...bool 	atEnd();  					// 到达文件尾部
bool	remove();  					// 删除文件
bool	rename(const QString & newName);	  // 重命名文件
qint64	read(char * data, qint64 maxSize);
QByteArray	read(qint64 maxSize);  	// 读取最大maxSize字节,并返回一个QByteArray
QByteArray	readAll();  			// 读取文件中所有数据,并返回一个QByteArrayqint64	write(const char * data, qint64 maxSize);
qint64	write(const QByteArray & byteArray);qint64	pos() const;  				// 得到当前读写指针的位置
bool 	seek(qint64 pos);  			// 重新设置读写指针位置bool QFileDevice::resize(qint64 sz); 	// 重设文件大小,可用于清空文件,比如 resize(0) qint64 size() const;				// 获取文件大小

💡 简易记事本的实现(part 2)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QtWidgets>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();private slots:void on_action_O_triggered();void on_action_S_triggered();private:Ui::MainWindow *ui;
};#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);this->setWindowTitle("新建文本文档 - txt");this->setWindowIcon(QIcon("://notepad.png"));
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_action_O_triggered()
{ui->statusBar->showMessage("Hello~", 0);QString filename = QFileDialog::getOpenFileName(this, tr("打开文件"), \".", tr("text  (*.c  *.cpp  *.txt)"));if (filename.isEmpty()){ui->statusBar->showMessage("打开失败", 1500);return ;}QFile file(filename);if (!file.open(QIODevice::ReadOnly)){ui->statusBar->showMessage("打开失败", 1500);return ;}ui->statusBar->showMessage("打开成功", 1500);QByteArray buffer = file.readAll();ui->textEdit->setText(QString(buffer));
//    ui->textEdit->setText(QString::fromUtf8(buffer));     // 可以//    QString str = QString::fromLocal8Bit(buffer);         // 不行,因为下面是 toUtf8
//    ui->textEdit->setText(QString(str));            }void MainWindow::on_action_S_triggered()
{QString filename = QFileDialog::getSaveFileName(this, tr("保存文件"), \QDir::homePath(), tr("text  (*.txt)"));if (filename.isEmpty()){ui->statusBar->showMessage("保存失败", 1500);return ;}QFile file(filename);if (!file.open(QIODevice::WriteOnly | QIODevice::Text)){ui->statusBar->showMessage("保存失败", 1500);return ;}QTextStream out(&file);QString str = ui->textEdit->toPlainText();QByteArray buffer;buffer.clear();buffer = str.toUtf8();out << buffer;          // file.write(buffer);ui->statusBar->showMessage("保存成功", 1500);file.close();
}

QIODevice::Text 是一种打开方式,用于文件的读写操作。当以 QIODevice::Text 方式打开文件时,在读取文件内容时,回车换行符(\r\n)会被自动转换为换行符(\n);在写入文件内容时,换行符(\n)会被自动转换为系统的换行符。
在这里插入图片描述

编码转换

QT 界面只支持 utf-8 编码。

QString	fromLocal8Bit(const QByteArray &str);  	// 将QByteArray按照本地编码转换为QString
QString	fromUtf8(const QByteArray &str); 		// 将QByteArray按照utf-8编码转换为QStringQByteArray	toLocal8Bit(); 			// 把QString按照本地编码转换成QByteArray
QByteArray	toUtf8(); 				// 把QString按照utf-8编码转换成QByteArray

事件

概念

事件由 窗口系统 或 QT 自身 以及 外部外设 产生,用以响应各种行为或情况。如:当按下鼠标或释放鼠标时,会产生鼠标事件;按下键盘时出现按键事件。窗体有时需要捕捉这些事件并做出业务逻辑处理。

步骤

文字描述版:

所有的事件处理都是通过重写某个事件方法来实现的

在这里插入图片描述

图片展示版:(以 QEvent::KeyPress 为例)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

💡 完善登录模块

要求:按回车键触发登录事件,按ESC 键退出登录界面。

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QtWidgets>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>class Widget : public QWidget
{Q_OBJECTQPushButton *btn;QLineEdit *username;QLineEdit *password;QString usr;QString pwd;QLabel *label;QLabel *ulabel;QLabel *plabel;public:Widget(QWidget *parent = 0);~Widget();public slots:void verifySlot();protected:void keyPressEvent(QKeyEvent * event);};

widget.cpp

#include "widget.h"
#include <QDebug>Widget::Widget(QWidget *parent): QWidget(parent)
{resize(480, 300);btn = new QPushButton("Login", this);       // 需要在堆区创建,不能在栈区创建btn->move(180, 220);ulabel = new QLabel("Username: ", this);ulabel->move(60, 80);username = new QLineEdit(this);username->move(180, 80);username->setPlaceholderText("Please input...");plabel = new QLabel("Password: ", this);plabel->move(60, 160);password = new QLineEdit(this);password->move(180, 160);password->setEchoMode(QLineEdit::Password);password->setPlaceholderText("Please input...");QObject::connect(btn, SIGNAL(clicked()), this, SLOT(verifySlot()));label = new QLabel(this);
}void Widget::verifySlot()
{usr = username->text();pwd = password->text();label->resize(480, 300);if (usr == "0828" && pwd == "0828"){
//        label->setText("Logined successfully!");             // 成功显示,但不美观qDebug("Logined successfully!");this->close();QWidget *homePage = new QWidget;homePage->resize(309, 500);homePage->show();}else{// QObject::connect(btn, SIGNAL(clicked()), this, SLOT(close()));          // 不能这样写,需要点击两次按钮才会关闭小窗口this->close();}
}void Widget::keyPressEvent(QKeyEvent * event)
{
//    qDebug("%x", event->key());if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)this->verifySlot();else if(event->key() == Qt::Key_Escape)this->close();elseQWidget::keyPressEvent(event);
}Widget::~Widget()
{}

💡 禁止输入特殊字符

在这里插入图片描述

弹框

QToolTip::showText(this->mapToGlobal(this->pos()), "不能使用特殊字符", this);

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "mytextedit.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);MyTextEdit *mine = new MyTextEdit(this);
}Widget::~Widget()
{delete ui;
}

mytextedit.h

#ifndef MYTEXTEDIT_H
#define MYTEXTEDIT_H#include <QTextEdit>
#include <QtWidgets>class MyTextEdit : public QTextEdit				// .cpp, Line 25
{Q_OBJECT
public:explicit MyTextEdit(QWidget *parent = 0);signals:public slots:protected:void keyPressEvent(QKeyEvent * event);};#endif // MYTEXTEDIT_H

mytextedit.cpp

#include "mytextedit.h"MyTextEdit::MyTextEdit(QWidget *parent) :QTextEdit(parent)
{
}void MyTextEdit::keyPressEvent(QKeyEvent * event)
{qDebug("%x", event->key());switch(event->key()){case Qt::Key_Backslash:			// 5c、case Qt::Key_Slash:				// 2f、case Qt::Key_Colon:				// 3a、case Qt::Key_Asterisk:			// 2a、case Qt::Key_Question:			// 3f、case Qt::Key_QuoteDbl:			// 22、case Qt::Key_Less:				// 3c、case Qt::Key_Greater:			// 3e、case Qt::Key_Bar:				// 7cQToolTip::showText(this->mapToGlobal(this->pos()), "不能使用特殊字符", this);break;default:QTextEdit::keyPressEvent(event);		// .h, Line 7break;}
//    if (event->key() == Qt::Key_Backslash)
//        QToolTip::showText(this->mapToGlobal(this->pos()), "不能使用特殊字符", this);
//    else
//        QTextEdit::keyPressEvent(event);
}

运行结果如下:
在这里插入图片描述
在这里插入图片描述

💡 使用鼠标滚轮 操作双向进度条

int numDegrees = event->delta() / 8;		// 滚动的角度,*8就是鼠标滚动的距离
int numSteps = numDegrees / 15;				// 滚动的步数,*15就是鼠标滚动的角度// numSteps即上下滚动的步数,体现到数值上是 1/-1。相关事件类:QWheelEvent

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QtWidgets>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();private:Ui::Widget *ui;QProgressBar *lbar;QProgressBar *rbar;int lval;int rval;protected:void wheelEvent(QWheelEvent * event);
};#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);this->resize(600, 50);// 初始化两个进度条lbar = new QProgressBar;rbar = new QProgressBar;// 为进度条设置默认值lbar->setValue(0);rbar->setValue(0);this->lval= 0;this->rval= 0;// 取消显示进度条的百分比lbar->setTextVisible(false);rbar->setTextVisible(false);// 使进度条可以纵向拉伸lbar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);rbar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);// 翻转左进度条lbar->setInvertedAppearance(true);// 添加进度条样式,每个进度条中包含有 1px 的 border边框// lbar->setStyleSheet(PROGRESS_LEFT_STYLE);// rbar->setStyleSheet(PROGRESS_RIGHT_STYLE);// 左右两进度条横向布局QHBoxLayout *box = new QHBoxLayout;box->addWidget(lbar);box->addWidget(rbar);box->setMargin(0);box->setSpacing(0);// 添加进度条两侧的空白,再次横向布局QHBoxLayout *hbox = new QHBoxLayout;hbox->addStretch(1);hbox->addLayout(box, 28);hbox->addStretch(1);hbox->setMargin(0);hbox->setSpacing(0);// 添加进度条上下的空白,然后纵向布局QVBoxLayout *vbox = new QVBoxLayout(this);vbox->addStretch(1);vbox->addLayout(hbox, 5);vbox->addStretch(1);vbox->setMargin(0);vbox->setSpacing(0);
}void Widget::wheelEvent(QWheelEvent * event)
{int numDegrees = event->delta() / 8;int numSteps = numDegrees / 15;//    qDebug() << numDegrees << numSteps;       // ±15, ±1if (numDegrees < 0){if (this->rval < 0){this->rval = 0;this->lval += 10;if (this->lval >= 100)this->lval = 100;lbar->setValue(this->lval);qDebug() << "left: " << this->lval;}this->rval -= 10;rbar->setValue(this->rval);qDebug() << "right: " << this->rval;}else if (numDegrees > 0){if (this->lval < 0){this->lval = 0;this->rval += 10;if (this->rval >= 100)this->rval = 100;rbar->setValue(this->rval);qDebug() << "right: " << this->rval;}this->lval -= 10;lbar->setValue(this->lval);qDebug() << "left: " << this->lval;}else { }
}Widget::~Widget()
{delete ui;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/209365.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java8 常用code

文章目录 前言一、lambda1. 排序1.1 按照对象属性排序&#xff1a;1.2 字符串List排序&#xff1a;1.3 数据库排序jpa 2. 聚合2.1 基本聚合&#xff08;返回对象list&#xff09;2.2 多字段组合聚合&#xff08;直接返回对象list数量&#xff09; 二、基础语法2.1 List2.1.1 数…

Holynix

信息收集阶段 存活主机探测&#xff1a;arp-scan -l 当然了&#xff0c;正常来说我们不应该使用arp进行探测&#xff0c;arp探测的是arp的缓存表&#xff0c;我们应该利用nmap进行探测&#xff01; nmap -sT --min-rate 10000 192.168.182.0/24 端口探测 nmap -sT --min-rat…

Navicat 技术指引 | 适用于 GaussDB 分布式的调试器

Navicat Premium&#xff08;16.3.3 Windows 版或以上&#xff09;正式支持 GaussDB 分布式数据库。GaussDB 分布式模式更适合对系统可用性和数据处理能力要求较高的场景。Navicat 工具不仅提供可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结…

golang学习笔记——数据结构进阶

文章目录 数据结构进阶mapmap示例sliceinterfaceembedded 数据结构进阶 map map 读取某个值时 - 返回结果可以为 value,bool 或者 value。注意后者&#xff0c;在key不存在时&#xff0c;会返回value对应类型的默认值map 的 range 方法需要注意 - key,value 或者 key。注意后…

【数据结构】单调栈与单调队列算法总结

单调栈 知识概览 单调栈最常见的应用是找到每一个数离它最近的且比它小的数。单调栈考虑的方式和双指针类似&#xff0c;都是先想一下暴力做法是什么&#xff0c;然后再挖掘一些性质如单调性&#xff0c;最终可以把目光集中在比较少的状态中&#xff0c;从而达到降低时间复杂…

业务设计原则

《亿级流量网站架构核心技术》读书笔记 一、防重设计 防重是通过在尽可能前端的位置阻挡请求重复执行&#xff0c;从而防止影响业务。它主要运用于“重复发生会造成业务影响”的场景。 请求本身可以发生多次&#xff0c;需要定义何为同一条业务数据。 分成业务本身允许多次和…

JS中call()、apply()、bind()改变this指向的原理

大家如果想了解改变this指向的方法&#xff0c;大家可以阅读本人的这篇改变this指向的六种方法 大家有没有想过这三种方法是如何改变this指向的&#xff1f;我们可以自己写吗&#xff1f; 答案是&#xff1a;可以自己写的 让我为大家介绍一下吧&#xff01; 1.call()方法的原理…

Python 语言在 Web 开发上有哪些应用框架?

Python 是一门多用途的编程语言&#xff0c;其简洁、易读且强大的特性使其成为Web开发领域的一种热门选择。Python Web开发框架提供了丰富的工具和功能&#xff0c;使得开发者能够更高效地构建各种规模和类型的Web应用。以下是一些在Python Web开发中常用的框架&#xff0c;每个…

[mysql]linux安装mysql5.7

之前安装的时候遇到了很多问题&#xff0c;浪费了一些时间。整理出这份教程&#xff0c;照着做基本一遍过。 这是安装包: 链接&#xff1a;https://pan.baidu.com/s/1gBuQBjA4R5qRYZKPKN3uXw?pwd1nuz 1.下载安装包&#xff0c;上传到linux。我这里就放到downloads目录下面…

WaitGroup原理分析

背景 在实际业务开发中&#xff0c;我们会遇到以下场景&#xff1a;请求数据库&#xff0c;批量获取1000条数据记录后&#xff0c;处理数据 为了减少因一次批量获取的数据太多&#xff0c;导致的数据库延时增加&#xff0c;我们可以把一次请求拆分成多次请求&#xff0c;并发去…

C#-快速剖析文件和流,并使用

目录 一、概述 二、文件系统 1、检查驱动器信息 2、Path 3、文件和文件夹 三、流 1、FileStream 2、StreamWriter与StreamReader 3、BinaryWriter与BinaryReader 一、概述 文件&#xff0c;具有永久存储及特定顺序的字节组成的一个有序、具有名称的集合&#xff1b; …

大模型的全方位评估

摘要&#xff1a; 评估通过提供一种跟踪进度、理解模型以及记录其能力和偏差的方法&#xff0c;为基础大模型提供了背景。基础大模型挑战了机器学习中标准评估范式实现这些目标的能力&#xff0c;因为它们距离特定任务只有一步之遥。为了设想适合基础模型的评估新范式&#xff…

枚举 LeetCode2048. 下一个更大的数值平衡数

如果整数 x 满足&#xff1a;对于每个数位 d &#xff0c;这个数位 恰好 在 x 中出现 d 次。那么整数 x 就是一个 数值平衡数 。 给你一个整数 n &#xff0c;请你返回 严格大于 n 的 最小数值平衡数 。 如果n的位数是k&#xff0c;n它的下一个大的平衡数一定不会超过 k1个k1…

图论——最小生成树

图论——最小生成树 A wise man changes his mind, a fool never will 生成树 一个连通图的生成树是一个极小的连通子图&#xff0c;它包含图中全部的n个顶点&#xff0c;但只有构成一棵树的n-1条边。 最小生成树 在这些边中选择N-1条出来&#xff0c;连接所有的N个点。这N-1…

Java后端的登录、注册接口是怎么实现的

目录 Java后端的登录、注册接口是怎么实现的 Java后端的登录接口是怎么实现的 Java后端的注册接口怎么实现&#xff1f; 如何防止SQL注入攻击&#xff1f; Java后端的登录、注册接口是怎么实现的 Java后端的登录接口是怎么实现的 Java后端的登录接口的实现方式有很多种&a…

使用git出现的问题

保证 首先保证自己的git已经下载 其次保证自己的gitee账号已经安装并且已经生成ssh公钥 保证自己要push的代码在要上传的文件夹内并且配置文件等都在父文件夹&#xff08;也就是文件没有套着文件&#xff09; 问题 1 $ git push origin master gitgitee.com: Permission de…

近似同态加密的 IND/SIM-CPA+ 安全性:对于 CKKS 实际有效的攻击

参考文献&#xff1a; [LM21] Li B, Micciancio D. On the security of homomorphic encryption on approximate numbers[C]//Advances in Cryptology–EUROCRYPT 2021: 40th Annual International Conference on the Theory and Applications of Cryptographic Techniques, Z…

【Linux】命令expect使用详解

&#x1f984; 个人主页——&#x1f390;个人主页 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; 感谢点赞和关注 &#xff0c;每天进步一点点&#xff01;加油&#xff01;&…

【上海大学数字逻辑实验报告】五、记忆元件测试

一、实验目的 掌握R-S触发器、D触发器和JK触发器的工作原理及其相互转换。学会用74LS00芯片构成钟控RS触发器。学会用74LS112实现D触发器学会在Quartus II上用D触发器实现JK触发器。 二、实验原理 基本R-S触发器是直接复位-置位的触发器&#xff0c;它是构成各种功能的触发器…

AI文档助手,当下热门的AI文档助手【2024】

在当今信息爆炸的时代&#xff0c;文档创作的需求愈发庞大。为了满足用户对高效、准确、原创性文档的需求&#xff0c;人工智能技术的应用日益广泛。本文将专心分享AI文档助手领域的热门推荐。 AI文档助手的背景与应用 AI文档助手作为人工智能技术在文档创作领域的一大应用&am…