当前位置: 首页 > news >正文

C++学习之路(十一)C++ 用Qt5实现一个工具箱(增加一个进制转换器功能)- 示例代码拆分讲解

上篇文章,我们用 Qt5 实现了在小工具箱中添加了《时间戳转换功能》功能。为了继续丰富我们的工具箱,今天我们就再增加一个平时经常用到的功能吧,就是「 进制转换 」功能。下面我们就来看看如何来规划开发一个这样的小功能并且添加到我们的工具箱中吧。

老规矩,先看效果

在这里插入图片描述

本次功能概述

这个程序是一个数字进制转换器,它能够将输入的数字按照不同的进制进行转换,并显示出转换后的结果。

  1. 界面布局:界面上分为两个排列方式不同的部分。第一个部分包含一个输入框和一个下拉选择框,它们水平排列。输入框接受用户输入数字,下拉选择框则用于选择转换后的进制。第二部分包含四个输出框,垂直排列,用于显示转换后的结果。

  2. 槽函数与转换:当用户在输入框中输入数字或者选择不同的进制时,程序会触发convertNumber函数。这个函数根据用户输入和选择的进制进行转换。根据不同的进制选择,程序会采取不同的转换方法,包括二进制、八进制、十进制和十六进制。

  3. 实时更新:输入框的内容一旦发生变化,就会实时计算出对应的四个输出框的结果。这种实时更新让用户能够方便地观察不同进制之间的转换关系。

  4. 清空功能:如果用户清空了输入框的内容,四个输出框也会相应地清空,避免显示错误的转换结果。

这个程序实现了简单的数字进制转换功能,并提供了实时更新和清空功能,使用户能够方便地在不同进制之间进行转换和比较。

核心代码实现

class NumberBaseConverter : public QWidget {
Q_OBJECT
public:explicit NumberBaseConverter(QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);// 横向排列的输入框和选择框auto *horizontalLayout = new QHBoxLayout();// 创建输入框并添加到水平布局inputLineEdit = new QLineEdit(this);horizontalLayout->addWidget(inputLineEdit);// 连接输入框的文本变化信号到槽函数connect(inputLineEdit, &QLineEdit::textChanged, this, &NumberBaseConverter::convertNumber);// 创建下拉选择框并添加到水平布局baseComboBox = new QComboBox(this);baseComboBox->addItem("二进制");baseComboBox->addItem("八进制");baseComboBox->addItem("十进制");baseComboBox->addItem("十六进制");horizontalLayout->addWidget(baseComboBox);// 将水平布局添加到垂直布局layout->addLayout(horizontalLayout);// 创建四个只读的输出框并添加到垂直布局binaryOutput = new QLineEdit(this);binaryOutput->setReadOnly(true);layout->addWidget(binaryOutput);octalOutput = new QLineEdit(this);octalOutput->setReadOnly(true);layout->addWidget(octalOutput);decimalOutput = new QLineEdit(this);decimalOutput->setReadOnly(true);layout->addWidget(decimalOutput);hexOutput = new QLineEdit(this);hexOutput->setReadOnly(true);layout->addWidget(hexOutput);// 连接下拉选择框的选择变化信号到槽函数,并进行初始转换connect(baseComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &NumberBaseConverter::convertNumber);convertNumber(); // 初始转换setLayout(layout); // 设置整体布局}private slots:void convertNumber() {QString inputText = inputLineEdit->text();bool ok;int base = baseComboBox->currentIndex();if (!inputText.isEmpty()) {// 根据所选进制进行转换if (base == 0) {int number = inputText.toInt(&ok, 2); // 二进制转十进制if (ok) {binaryOutput->setText(inputText);octalOutput->setText(QString::number(number, 8));decimalOutput->setText(QString::number(number));hexOutput->setText(QString::number(number, 16).toUpper());}} else if (base == 1) {// 八进制转换int number = inputText.toInt(&ok, 8);if (ok) {binaryOutput->setText(QString::number(number, 2));octalOutput->setText(inputText);decimalOutput->setText(QString::number(number));hexOutput->setText(QString::number(number, 16).toUpper());}} else if (base == 2) {// 十进制转换int number = inputText.toInt(&ok, 10);if (ok) {binaryOutput->setText(QString::number(number, 2));octalOutput->setText(QString::number(number, 8));decimalOutput->setText(inputText);hexOutput->setText(QString::number(number, 16).toUpper());}} else if (base == 3) {// 十六进制转换int number = inputText.toInt(&ok, 16);if (ok) {binaryOutput->setText(QString::number(number, 2));octalOutput->setText(QString::number(number, 8));decimalOutput->setText(QString::number(number));hexOutput->setText(inputText.toUpper());}}} else {// 如果输入为空,则清空输出binaryOutput->clear();octalOutput->clear();decimalOutput->clear();hexOutput->clear();}}private:QLineEdit *inputLineEdit;QComboBox *baseComboBox;QLineEdit *binaryOutput;QLineEdit *octalOutput;QLineEdit *decimalOutput;QLineEdit *hexOutput;
};

伸手党福利时间,上完整代码:

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QDebug>
#include <QListWidget>
#include <QClipboard>
#include <QMimeData>
#include <QTextEdit>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDateTime>
#include <QLabel>
#include <QComboBox>
#include <QLineEdit>#define myApp (dynamic_cast<QApplication *>(QCoreApplication::instance()))class NumberBaseConverter : public QWidget {
Q_OBJECT
public:explicit NumberBaseConverter(QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);// 横向排列的输入框和选择框auto *horizontalLayout = new QHBoxLayout();// 创建输入框并添加到水平布局inputLineEdit = new QLineEdit(this);horizontalLayout->addWidget(inputLineEdit);// 连接输入框的文本变化信号到槽函数connect(inputLineEdit, &QLineEdit::textChanged, this, &NumberBaseConverter::convertNumber);// 创建下拉选择框并添加到水平布局baseComboBox = new QComboBox(this);baseComboBox->addItem("二进制");baseComboBox->addItem("八进制");baseComboBox->addItem("十进制");baseComboBox->addItem("十六进制");horizontalLayout->addWidget(baseComboBox);// 将水平布局添加到垂直布局layout->addLayout(horizontalLayout);// 创建四个只读的输出框并添加到垂直布局binaryOutput = new QLineEdit(this);binaryOutput->setReadOnly(true);layout->addWidget(binaryOutput);octalOutput = new QLineEdit(this);octalOutput->setReadOnly(true);layout->addWidget(octalOutput);decimalOutput = new QLineEdit(this);decimalOutput->setReadOnly(true);layout->addWidget(decimalOutput);hexOutput = new QLineEdit(this);hexOutput->setReadOnly(true);layout->addWidget(hexOutput);// 连接下拉选择框的选择变化信号到槽函数,并进行初始转换connect(baseComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &NumberBaseConverter::convertNumber);convertNumber(); // 初始转换setLayout(layout); // 设置整体布局}private slots:void convertNumber() {QString inputText = inputLineEdit->text();bool ok;int base = baseComboBox->currentIndex();if (!inputText.isEmpty()) {// 根据所选进制进行转换if (base == 0) {int number = inputText.toInt(&ok, 2); // 二进制转十进制if (ok) {binaryOutput->setText(inputText);octalOutput->setText(QString::number(number, 8));decimalOutput->setText(QString::number(number));hexOutput->setText(QString::number(number, 16).toUpper());}} else if (base == 1) {// 八进制转换int number = inputText.toInt(&ok, 8);if (ok) {binaryOutput->setText(QString::number(number, 2));octalOutput->setText(inputText);decimalOutput->setText(QString::number(number));hexOutput->setText(QString::number(number, 16).toUpper());}} else if (base == 2) {// 十进制转换int number = inputText.toInt(&ok, 10);if (ok) {binaryOutput->setText(QString::number(number, 2));octalOutput->setText(QString::number(number, 8));decimalOutput->setText(inputText);hexOutput->setText(QString::number(number, 16).toUpper());}} else if (base == 3) {// 十六进制转换int number = inputText.toInt(&ok, 16);if (ok) {binaryOutput->setText(QString::number(number, 2));octalOutput->setText(QString::number(number, 8));decimalOutput->setText(QString::number(number));hexOutput->setText(inputText.toUpper());}}} else {// 如果输入为空,则清空输出binaryOutput->clear();octalOutput->clear();decimalOutput->clear();hexOutput->clear();}}private:QLineEdit *inputLineEdit;QComboBox *baseComboBox;QLineEdit *binaryOutput;QLineEdit *octalOutput;QLineEdit *decimalOutput;QLineEdit *hexOutput;
};class PlaceholderTextEdit : public QWidget {
Q_OBJECT
public:explicit PlaceholderTextEdit(const QString &placeholderText, QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);placeholderLabel = new QLabel(placeholderText, this);layout->addWidget(placeholderLabel);textEdit = new QTextEdit(this);layout->addWidget(textEdit);connect(textEdit, &QTextEdit::textChanged, this, &PlaceholderTextEdit::checkPlaceholder);checkPlaceholder(); // 初始检查setLayout(layout);}QString getText() const {return textEdit->toPlainText();}private slots:void checkPlaceholder() {placeholderLabel->setVisible(textEdit->toPlainText().isEmpty());}private:QLabel *placeholderLabel;QTextEdit *textEdit;
};class DateTimeTimestampConverter : public QWidget {
Q_OBJECT
public:explicit DateTimeTimestampConverter(QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);inputTextEdit = new PlaceholderTextEdit("在此输入日期时间或时间戳", this);layout->addWidget(inputTextEdit);convertToTimestampButton = new QPushButton("日期时间转时间戳", this);connect(convertToTimestampButton, &QPushButton::clicked, this, &DateTimeTimestampConverter::convertToTimestamp);layout->addWidget(convertToTimestampButton);convertToDateTimeButton = new QPushButton("时间戳转日期时间", this);connect(convertToDateTimeButton, &QPushButton::clicked, this, &DateTimeTimestampConverter::convertToDateTime);layout->addWidget(convertToDateTimeButton);outputTextEdit = new QTextEdit(this);outputTextEdit->setReadOnly(true);layout->addWidget(outputTextEdit);setLayout(layout);}private slots:void convertToTimestamp() {QString inputText = inputTextEdit->getText();QDateTime dateTime = QDateTime::fromString(inputText, "yyyy-MM-dd HH:mm:ss");if (dateTime.isValid()) {qint64 timestamp = dateTime.toSecsSinceEpoch();outputTextEdit->setText(QString::number(timestamp));} else {outputTextEdit->setText("无效的日期时间格式!");}}void convertToDateTime() {QString inputText = inputTextEdit->getText();bool ok;qint64 timestamp = inputText.toLongLong(&ok);if (ok) {QDateTime dateTime;dateTime.setSecsSinceEpoch(timestamp);outputTextEdit->setText("时间戳 " + inputText + " 对应的日期时间是:" + dateTime.toString("yyyy-MM-dd HH:mm:ss"));} else {outputTextEdit->setText("无效的时间戳格式!");}}private:QPushButton *convertToTimestampButton;QPushButton *convertToDateTimeButton;QTextEdit *outputTextEdit;PlaceholderTextEdit *inputTextEdit;
};class JsonFormatter : public QWidget {
Q_OBJECT
public:explicit JsonFormatter(QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);inputTextEdit = new QTextEdit(this);layout->addWidget(inputTextEdit);formatButton = new QPushButton("格式化", this);connect(formatButton, &QPushButton::clicked, this, &JsonFormatter::formatJson);layout->addWidget(formatButton);outputTextEdit = new QTextEdit(this);outputTextEdit->setReadOnly(true);layout->addWidget(outputTextEdit);setLayout(layout);}private slots:void formatJson() {QString inputText = inputTextEdit->toPlainText();QJsonParseError error{};QJsonDocument jsonDoc = QJsonDocument::fromJson(inputText.toUtf8(), &error);if (error.error != QJsonParseError::NoError) {outputTextEdit->setText("JSON 解析错误:" + error.errorString());return;}QJsonObject jsonObj = jsonDoc.object();QJsonDocument formattedJson(jsonObj);outputTextEdit->setText(formattedJson.toJson());}private:QTextEdit *inputTextEdit;QPushButton *formatButton;QTextEdit *outputTextEdit;
};class ClipboardManager : public QWidget {
Q_OBJECT
public:explicit ClipboardManager(QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);listWidget = new QListWidget(this);updateList(); // 初始更新列表auto *clearButton = new QPushButton("清空记录", this);connect(clearButton, &QPushButton::clicked, this, &ClipboardManager::clearClipboard);layout->addWidget(listWidget);layout->addWidget(clearButton);setLayout(layout);connect(myApp->clipboard(), &QClipboard::dataChanged, this, &ClipboardManager::updateList);}private slots:void updateList() {const QClipboard *clipboard = myApp->clipboard();const QMimeData *mimeData = clipboard->mimeData();if (mimeData->hasText()) {const QString clipboardText = mimeData->text();if (!clipboardText.isEmpty()) {listWidget->addItem(clipboardText);}}}void clearClipboard() {myApp->clipboard()->clear();listWidget->clear();}private:QListWidget *listWidget;
};class MyMainWindow : public QWidget {
Q_OBJECT
public:explicit MyMainWindow(QWidget *parent = nullptr) : QWidget(parent) {setWindowTitle("天河工具箱");auto *layout = new QVBoxLayout(this);auto *clipboardButton = new QPushButton("显示管理粘贴板记录");clipboardButton->setObjectName("clipboardButton");connect(clipboardButton, &QPushButton::clicked, this, &MyMainWindow::toggleClipboardManager);clipboardManager = new ClipboardManager(this);clipboardManager->hide();layout->addWidget(clipboardManager);layout->addWidget(clipboardButton);auto *jsonFormatButton = new QPushButton("显示格式化 JSON");jsonFormatButton->setObjectName("jsonFormatButton");connect(jsonFormatButton, &QPushButton::clicked, this, &MyMainWindow::toggleJsonFormatter);jsonFormatter = new JsonFormatter(this);jsonFormatter->hide();layout->addWidget(jsonFormatter);layout->addWidget(jsonFormatButton);auto *timestampConverterButton = new QPushButton("显示时间戳转换");timestampConverterButton->setObjectName("timestampConverterButton");connect(timestampConverterButton, &QPushButton::clicked, this, &MyMainWindow::toggleDateTimeTimestampConverter);timestampConverter = new DateTimeTimestampConverter(this);timestampConverter->hide();layout->addWidget(timestampConverter);layout->addWidget(timestampConverterButton);auto *numberBaseConverterButton = new QPushButton("显示进制转换器");numberBaseConverterButton->setObjectName("numberBaseConverterButton");connect(numberBaseConverterButton, &QPushButton::clicked, this, &MyMainWindow::toggleNumberBaseConverter);numberBaseConverter = new NumberBaseConverter(this);numberBaseConverter->hide();layout->addWidget(numberBaseConverter);layout->addWidget(numberBaseConverterButton);setLayout(layout);}private slots:void toggleClipboardManager() {auto* curButton = findChild<QPushButton*>("clipboardButton");if (clipboardManager->isHidden()) {if (curButton) {curButton->setText("隐藏管理粘贴板记录");}clipboardManager->show();} else {if (curButton) {curButton->setText("显示管理粘贴板记录");}clipboardManager->hide();}}void toggleJsonFormatter() {auto* curButton = findChild<QPushButton*>("jsonFormatButton");if (jsonFormatter->isHidden()) {if (curButton) {curButton->setText("隐藏格式化 JSON");}jsonFormatter->show();} else {if (curButton) {curButton->setText("显示格式化 JSON");}jsonFormatter->hide();}}void toggleDateTimeTimestampConverter() {auto* curButton = findChild<QPushButton*>("timestampConverterButton");if (timestampConverter->isHidden()) {if (curButton) {curButton->setText("隐藏时间戳转换");}timestampConverter->show();} else {if (curButton) {curButton->setText("显示时间戳转换");}timestampConverter->hide();}}void toggleNumberBaseConverter() {auto* curButton = findChild<QPushButton*>("numberBaseConverterButton");if (numberBaseConverter->isHidden()) {if (curButton) {curButton->setText("隐藏进制转换器");}numberBaseConverter->show();} else {if (curButton) {curButton->setText("显示进制转换器");}numberBaseConverter->hide();}}private:ClipboardManager *clipboardManager;JsonFormatter *jsonFormatter;DateTimeTimestampConverter *timestampConverter;NumberBaseConverter *numberBaseConverter;
};int main(int argc, char *argv[]) {QApplication a(argc, argv);MyMainWindow mainWindow;mainWindow.show();return QApplication::exec();
}#include "main.moc"

拆分讲解

本次核心代码相对好理解一些,就不逐段讲解了,就只贴出来我们用到的相关控件函数吧。

控件介绍

  • QVBoxLayout:垂直布局管理器,用于垂直排列子部件。
  • QHBoxLayout:水平布局管理器,用于水平排列子部件。
  • QLineEdit:单行文本输入框,用于输入文本。
  • QComboBox:下拉选择框,提供一个可选择的下拉列表。
  • QPushButton:按钮控件,用于触发特定操作或槽函数。
  • connect():QT中的信号与槽机制,用于连接信号和槽函数,当信号被触发时,相关的槽函数将被执行。

函数方法介绍

  • QHBoxLayout::addWidget():将子部件添加到水平布局中。
  • QVBoxLayout::addWidget():将子部件添加到垂直布局中。
  • QComboBox::addItem():向下拉选择框添加选项。
  • QLineEdit::setReadOnly():设置文本输入框为只读模式。
  • QLineEdit::clear():清空文本输入框中的内容。
  • QComboBox::currentIndex():获取当前选择的下拉列表索引。
  • QString::toInt():将字符串转换为整数,可以指定进制。
  • QString::number():将数字转换为字符串,可以指定进制。
  • QString::toUpper():将字符串转换为大写形式。

这些控件和函数方法是用于构建数字进制转换器的基础组件和功能。通过这些控件和方法,可以实现用户输入数字和选择进制,然后进行相应进制的转换,并在界面上显示转换结果。


讲解完毕,复制代码后,开始运行调试吧~

好了~ 本文就到这里了,感谢您的阅读,每天还有更多的实例学习文章等着你 🎆。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇。

相关文章:

C++学习之路(十一)C++ 用Qt5实现一个工具箱(增加一个进制转换器功能)- 示例代码拆分讲解

上篇文章&#xff0c;我们用 Qt5 实现了在小工具箱中添加了《时间戳转换功能》功能。为了继续丰富我们的工具箱&#xff0c;今天我们就再增加一个平时经常用到的功能吧&#xff0c;就是「 进制转换 」功能。下面我们就来看看如何来规划开发一个这样的小功能并且添加到我们的工具…...

C语言每日一题(40)栈实现队列

力扣232 用栈实现队列 题目描述 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移除并…...

Vue.js 的生命周期

Vue.js 的生命周期钩子函数是一组在 Vue 实例生命周期中执行的函数&#xff0c;它们允许你在特定阶段执行自定义逻辑。以下是 Vue.js 的生命周期钩子函数以及它们在生命周期中的执行时机&#xff1a; 1、beforeCreate: 在实例初始化之后&#xff0c;数据观测 (data observer)…...

SeaTunnel引擎下的SQL Server CDC解决方案:构建高效数据管道

在快速发展的数据驱动时代&#xff0c;实时数据处理已经成为企业决策和运营的关键因素。特别是在处理来自各种数据源的信息时&#xff0c;如何确保数据的及时、准确和高效同步变得尤为重要。本文着重介绍了如何利用 SqlServer CDC 源连接器在 SeaTunnel 框架下实现 SQL Server …...

【攻防世界-misc】Encode

1.下载解压文件&#xff0c;打开这个内容有些疑似ROT13加密&#xff0c;利用在线工具解密&#xff1a;ROT13解码计算器 - 计算专家 得到了解密后的值 得到解码结果后&#xff0c;看到是由数字和字母组成&#xff0c;再根据题目描述为套娃&#xff0c;猜测为base编码&#xff08…...

visual c++ 2019 redistributable package

直接安装下面包只有24M Microsoft Visual C Redistributable 2019 x86: https://aka.ms/vs/16/release/VC_redist.x86.exe x64: https://aka.ms/vs/16/release/VC_redist.x64.exe ———————————————— 版权声明&#xff1a;本文为CSDN博主「kpacnB_Z」的原创文章…...

WPF中DataGrid解析

效果如图&#xff1a; 代码如下&#xff1a; <DataGrid Grid.Row"1" x:Name"dataGrid" ItemsSource"{Binding DataList}" AutoGenerateColumns"False"SelectedItem"{Binding SelectedItem,UpdateSourceTriggerPropertyChange…...

在数据库中进行表内容的修改(MYSQL)

根据表中内容&#xff0c;用命令语句创建数据库&#xff0c;表格&#xff0c;以及插入&#xff0c;修改&#xff0c;删除表格中的内容。 创建数据库&#xff1a;zrzy mysql> create database zrzy; 引用zrzy数据库&#xff1a; mysql> use zrzy; 创建student_info表&…...

Android中的多进程

在Android中也可以像pc一样开启多进程&#xff0c;这在android的编程中通常是比较少见的&#xff0c;以为在一个app基本上都是单进程工作就已经足够了&#xff0c;有一些特殊的场景&#xff0c;我们需要用多进程来做一些额外的工作&#xff0c;比如下载工作等。 在Android的An…...

Apache2.4 AliasMatch导致301重定向问题?

环境&#xff1a;ubuntu18.04-desktop apache2版本&#xff1a; rootubuntu:/etc/apache2# apache2ctl -v Server version: Apache/2.4.29 (Ubuntu) Server built: 2023-03-08T17:34:33apache配置&#xff1a; DocumentRoot /var/www/html # Alias就没事 # Alias "/my…...

广州华锐视点:基于VR元宇宙技术开展法律法规常识在线教学,打破地域和时间限制

随着科技的飞速发展&#xff0c;人类社会正逐渐迈向一个全新的时代——元宇宙。元宇宙是一个虚拟的、数字化的世界&#xff0c;它将现实世界与数字世界紧密相连&#xff0c;为人们提供了一个全新的交流、学习和娱乐平台。在这个充满无限可能的元宇宙中&#xff0c;法律知识同样…...

Maven——Maven使用基础

1、安装目录分析 1.1、环境变量MAVEN_HOME 环境变量指向Maven的安装目录&#xff0c;如下图所示&#xff1a; 下面看一下该目录的结构和内容&#xff1a; bin&#xff1a;该目录包含了mvn运行的脚本&#xff0c;这些脚本用来配置Java命令&#xff0c;准备好classpath和相关…...

U4_2:图论之MST/Prim/Kruskal

文章目录 一、最小生成树-MST生成MST策略一些定义 思路彩蛋 二、普里姆算法&#xff08;Prim算法&#xff09;思路算法流程数据存储分析 伪代码时间复杂度分析 三、克鲁斯卡尔算法&#xff08;Kruskal算法&#xff09;分析算法流程并查集-Find-set 伪代码时间复杂度分析 一、最…...

springboot 注解@JsonInclude

修饰 实体属性or实体类 //枚举值&#xff1a;ALWAYS,NON_NULL,NON_ABSENT,NON_EMPTY,NON_DEFAULT,CUSTOM,USE_DEFAULTS JsonInclude(Include.NON_EMPTY)//将该标记放在属性上&#xff0c;如果该属性为NULL则不参与序列化 //如果放在类上边,那对这个类的全部属性起作用 Inclu…...

Python 中文完整教程目录

Python 教程 Python 是一门易于学习、功能强大的编程语言。它提供了高效的高级数据结构&#xff0c;还能简单有效地面向对象编程。Python 优雅的语法和动态类型以及解释型语言的本质&#xff0c;使它成为多数平台上写脚本和快速开发应用的理想语言。 Python 官网&#xff08;…...

C/C++---------------LeetCode第35. 搜索插入位置

插入的位置 题目及要求二分查找在main内使用 题目及要求 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: …...

网络安全--基于Kali的网络扫描基础技术

文章目录 1. 标准ICMP扫描1.1使用Ping命令1.1.1格式1.1.2实战 1.2使用Nmap工具1.2.1格式1.2.2实战1.2.2.1主机在线1.2.2.2主机不在线 1.3使用Fping命令1.3.1格式1.3.2实战 2. 时间戳查询扫描2.1格式2.2实战 3. 地址掩码查询扫描3.1格式3.2实战 2. TCP扫描2.1TCP工作机制2.2TCP …...

C语言——求π的近似值

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> #include<math.h> int main() {int s;double n,t,pi;t1;pi0;n1.0;s1;while (fabs(t)>1e-6){pipit; nn2; s-s; ts/n;}pipi*4;printf("pi%lf\n",pi);return 0; }这里是求小数点后6位——1e-6&#…...

如何使用ffmpeg转换图片格式

ffmpeg简介与图片格式介绍 windows安装ffmpeg&#xff0c;从如下网站下载release版本 https://www.gyan.dev/ffmpeg/builds/ ffmpeg 6.1版本仍然不支持heic的图片格式&#xff0c;未来可能会支持&#xff0c;具体见该issue&#xff1a; https://trac.ffmpeg.org/ticket/6521 …...

11 动态规划解最后一块石头的重量II

来源&#xff1a;LeetCode第1049题 难度&#xff1a;中等 描述&#xff1a;有一堆石头&#xff0c;用证书数组stones表示&#xff0c;其中stones[i]表示第i块石头的重量&#xff0c;每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将他们放在一起粉碎&#xff0c;…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...