C++学习之路(十五)C++ 用Qt5实现一个工具箱(增加16进制颜色码转换和屏幕颜色提取功能)- 示例代码拆分讲解

news2024/12/27 2:36:37

上篇文章,我们用 Qt5 实现了在小工具箱中添加了《Base64图片编码预览功能》功能。为了继续丰富我们的工具箱,今天我们就再增加两个平时经常用到的功能吧,就是「 16进制颜色码转RGB文本 」和 「屏幕颜色提取」功能。下面我们就来看看如何来规划开发这样的小功能并且添加到我们的工具箱中吧。

老规矩,先上图

16进制转RGB

在这里插入图片描述

RGB转16进制

在这里插入图片描述

屏幕颜色提取

在这里插入图片描述

功能概述:颜色码转换和屏幕颜色提取

  1. 颜色码转换功能

    • 输入:支持输入RGB颜色代码或16进制颜色代码。
    • 输出:转换为另一种格式的颜色代码。
    • 操作:支持从RGB转换为16进制和反之转换。
  2. 屏幕颜色提取功能

    • 操作:捕获屏幕上鼠标位置的颜色信息。
    • 展示:显示提取到的颜色,包括16进制颜色代码和颜色预览。
    • 交互:启动功能后,可以在屏幕上移动鼠标以实时获取不同位置的颜色。
    • 终止:点击特定键盘按键(例如按下Tab键)以停止捕获。

需求概述:

  1. 颜色码转换功能

    • 用户友好:提供清晰的界面,支持输入RGB或16进制颜色代码。
    • 格式转换:允许用户在RGB和16进制颜色代码之间进行转换。
    • 展示结果:将转换后的颜色代码显示给用户。
  2. 屏幕颜色提取功能

    • 启动捕获:点击按钮启动颜色捕获功能。
    • 显示颜色:在界面上显示捕获到的颜色代码和颜色预览。
    • 实时更新:随着鼠标移动,实时显示不同位置的颜色。
    • 停止捕获:通过特定操作(例如按下Tab键)停止捕获颜色。
    • 异常处理:处理未找到屏幕或捕获颜色失败的情况。

这样的功能旨在提供一个便捷的界面,允许用户在RGB和16进制颜色代码之间自由转换,并且能够在屏幕上捕获颜色以获取准确的颜色信息。


核心代码实现

class ColorConverter : public QWidget {
Q_OBJECT
public:
    explicit ColorConverter(QWidget *parent = nullptr) : QWidget(parent) {
        // 在构造函数中初始化定时器
        colorTimer = new QTimer(this);
        colorTimer->setInterval(100); // 设置定时器间隔为100毫秒
        connect(colorTimer, &QTimer::timeout, this, &ColorConverter::extractScreenColor);

        auto *layout = new QVBoxLayout(this);

        // 创建颜色值转换部分的输入框和按钮
        colorInput = new QLineEdit(this);
        layout->addWidget(colorInput);

        convertButton = new QPushButton("16进制转RGB", this);
        connect(convertButton, &QPushButton::clicked, this, &ColorConverter::convertToRgbColor);
        layout->addWidget(convertButton);

        convertButton = new QPushButton("RGB转16进制", this);
        connect(convertButton, &QPushButton::clicked, this, &ColorConverter::convertToHexColor);
        layout->addWidget(convertButton);

        convertedColorOutput = new QTextEdit(this);
        convertedColorOutput->setReadOnly(true);
        layout->addWidget(convertedColorOutput);

        // 创建屏幕颜色提取器部分的按钮和显示框
        extractColorButton = new QPushButton("开始提取屏幕颜色", this);
        connect(extractColorButton, &QPushButton::clicked, this, &ColorConverter::startColorCapture);
        layout->addWidget(extractColorButton);

        // 创建用于存放颜色块和颜色输出的网格布局
        auto *colorBlockLayout = new QGridLayout();

        // 创建颜色输出
        screenColorOutput = new QLabel(this);
        screenColorOutput->setFixedSize(200, 90);
        screenColorOutput->setAlignment(Qt::AlignCenter);
        screenColorOutput->setStyleSheet("border: 1px solid #ddd");
        colorBlockLayout->addWidget(screenColorOutput, 0, 0); // 将颜色输出放在网格布局的左上角

        // 创建颜色块
        screenColorBlock = new QLabel(this);
        screenColorBlock->setFixedSize(30, 30); // 设置颜色块大小
        screenColorBlock->setStyleSheet("border: 1px solid #ddd");
        colorBlockLayout->addWidget(screenColorBlock, 0, 0, Qt::AlignTop | Qt::AlignRight); // 将颜色块放在颜色输出的右上角

        layout->addLayout(colorBlockLayout);

        setLayout(layout);

        installEventFilter(this); // 安装事件过滤器以捕获鼠标事件
    }

protected slots:

    void convertToHexColor() {
        // 从输入框获取颜色值
        QString colorText = colorInput->text();
        // 按逗号分隔RGB文本
        QStringList rgbValues = colorText.split(',');
        if (rgbValues.size() == 3) {
            // 获取R、G和B的值
            int red = rgbValues[0].toInt();
            int green = rgbValues[1].toInt();
            int blue = rgbValues[2].toInt();

            // 将RGB值转换为16进制字符串
            QString hexRed = QString("%1").arg(red, 2, 16, QChar('0')).toUpper();
            QString hexGreen = QString("%1").arg(green, 2, 16, QChar('0')).toUpper();
            QString hexBlue = QString("%1").arg(blue, 2, 16, QChar('0')).toUpper();

            // 构建16进制颜色代码文本
            QString hexText = QString("#%1%2%3").arg(hexRed).arg(hexGreen).arg(hexBlue);
            convertedColorOutput->setText(hexText);
        } else {
            // 处理无效颜色输入的情况
            convertedColorOutput->setText("Invalid color input");
        }
    }

    void convertToRgbColor() {
        // 从输入框获取颜色值
        QString colorText = colorInput->text();
        QColor color(colorText);
        if (color.isValid()) {
            // 获取16进制颜色码的红、绿、蓝通道值
            int red = color.red();
            int green = color.green();
            int blue = color.blue();
            // 构建RGB颜色代码文本
            QString outputText = QString("RGB(%1, %2, %3)").arg(red).arg(green).arg(blue);
            convertedColorOutput->setText(outputText);
        } else {
            // 处理无效颜色输入的情况
            convertedColorOutput->setText("Invalid color input");
        }
    }

    // 开始捕获颜色的槽函数
    void startColorCapture() {
        extractColorButton->setText("请开始移动鼠标 按Tab键终止取色");
        colorTimer->start();
    }

    void extractScreenColor() {
        QPoint cursorPos = QCursor::pos();
        QScreen *screen = QGuiApplication::screenAt(cursorPos);

        if (screen) {
            QPixmap screenshot = screen->grabWindow(0, cursorPos.x(), cursorPos.y(), 1, 1);
            if (!screenshot.isNull()) {
                QColor color = screenshot.toImage().pixel(0, 0);
                QString colorText = QString("Screen Color: #%1").arg(color.name().mid(1));
                screenColorOutput->setText(colorText);

                QString styleSheet = QString("background-color: %1; border: 1px solid #ddd;").arg(color.name());
                screenColorBlock->setStyleSheet(styleSheet);
            } else {
                screenColorOutput->setText("Failed to grab screen color");
            }
        } else {
            screenColorOutput->setText("No screen found at the cursor position");
        }
    }

    // 停止捕获颜色的槽函数
    void stopColorCapture() {
        colorTimer->stop();
        extractColorButton->setText("开始提取屏幕颜色");
    }
protected:
    // 捕获松开Tab按键事件
    bool eventFilter(QObject *watched, QEvent *event) override {
        if (event->type() == QEvent::WindowDeactivate || event->type() == QEvent::KeyRelease) {
            stopColorCapture();
            return true;
        }
        return QObject::eventFilter(watched, event);
    }

private:
    QLineEdit *colorInput;
    QPushButton *convertButton;
    QTextEdit *convertedColorOutput;
    QPushButton *extractColorButton;
    QLabel *screenColorOutput;
    QLabel *screenColorBlock;
    QTimer *colorTimer;
};

核心代码讲解

让我们逐段解析 ColorConverter 类的代码。

class ColorConverter : public QWidget {
Q_OBJECT
public:
    explicit ColorConverter(QWidget *parent = nullptr) : QWidget(parent) {
        // 在构造函数中初始化定时器
        colorTimer = new QTimer(this);
        colorTimer->setInterval(100); // 设置定时器间隔为100毫秒
        connect(colorTimer, &QTimer::timeout, this, &ColorConverter::extractScreenColor);

        auto *layout = new QVBoxLayout(this);
        // 创建颜色值转换部分的输入框和按钮
        colorInput = new QLineEdit(this);
        layout->addWidget(colorInput);
        // ...(略)
        installEventFilter(this); // 安装事件过滤器以捕获鼠标事件
    }
    // ...(略)
};
  1. 构造函数与定时器初始化:构造函数中创建了一个 ColorConverter 对象,并初始化了一个定时器 colorTimer。这个定时器用于每 100 毫秒触发一次屏幕颜色提取功能,并与 extractScreenColor 函数连接。

  2. 界面布局初始化:在构造函数中,使用了垂直布局管理器 QVBoxLayout,并添加了颜色输入框到布局中。

  3. 事件过滤器安装installEventFilter(this) 安装了一个事件过滤器来监视该对象所接收到的事件。在这个场景中,它用于捕获鼠标事件以停止颜色提取。

转换函数

void convertToHexColor() {
    // 获取输入框中的颜色值,转换为16进制
    // ...
}

void convertToRgbColor() {
    // 获取输入框中的颜色值,转换为RGB格式
    // ...
}
  • QLineEdit 和 QTextEdit:分别用于输入和显示颜色值,convertToHexColor 和 convertToRgbColor 函数用于颜色转换。

屏幕颜色提取器

void startColorCapture() {
    // 开始捕获颜色的槽函数
    // ...
}

void extractScreenColor() {
    // 提取屏幕颜色的槽函数
    // ...
}

void stopColorCapture() {
    // 停止颜色捕获的槽函数
    // ...
}
  • QPushButton 和 QLabel:extractColorButton 用于启动颜色捕获,screenColorOutput 和 screenColorBlock 用于显示屏幕颜色信息。

事件过滤器

bool eventFilter(QObject *watched, QEvent *event) override {
    // 事件过滤器,捕获键盘事件以终止颜色捕获
    // ...
}
  • QObject 和 QEvent:eventFilter 捕获键盘事件,当用户按下 Tab 键松开时终止颜色捕获。

总结

主要利用了 Qt 中的 QWidget、QObject、QTimer、QLineEdit、QPushButton、QTextEdit、QLabel 等部件,以及事件过滤器功能来实现颜色转换和屏幕颜色提取的功能。按钮的点击触发不同的槽函数,展示了转换后的颜色信息或从屏幕获取的颜色信息。同时,通过事件过滤器监听键盘事件,以实现终止屏幕颜色提取的功能。


讲解完毕,下面是完整代码,复制到本地跑一跑吧~

#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>
#include <QXmlStreamReader>
#include <QFile>
#include <QFileDialog>
#include <QScreen>
#include <QCursor>
#include <QPoint>
#include <QGuiApplication>
#include <QPixmap>
#include <QHBoxLayout>
#include <QThread>
#include <QMouseEvent>
#include <QTimer>

#define myApp (dynamic_cast<QApplication *>(QCoreApplication::instance()))

class ColorConverter : public QWidget {
Q_OBJECT
public:
    explicit ColorConverter(QWidget *parent = nullptr) : QWidget(parent) {
        // 在构造函数中初始化定时器
        colorTimer = new QTimer(this);
        colorTimer->setInterval(100); // 设置定时器间隔为100毫秒
        connect(colorTimer, &QTimer::timeout, this, &ColorConverter::extractScreenColor);

        auto *layout = new QVBoxLayout(this);

        // 创建颜色值转换部分的输入框和按钮
        colorInput = new QLineEdit(this);
        layout->addWidget(colorInput);

        convertButton = new QPushButton("16进制转RGB", this);
        connect(convertButton, &QPushButton::clicked, this, &ColorConverter::convertToRgbColor);
        layout->addWidget(convertButton);

        convertButton = new QPushButton("RGB转16进制", this);
        connect(convertButton, &QPushButton::clicked, this, &ColorConverter::convertToHexColor);
        layout->addWidget(convertButton);

        convertedColorOutput = new QTextEdit(this);
        convertedColorOutput->setReadOnly(true);
        layout->addWidget(convertedColorOutput);

        // 创建屏幕颜色提取器部分的按钮和显示框
        extractColorButton = new QPushButton("开始提取屏幕颜色", this);
        connect(extractColorButton, &QPushButton::clicked, this, &ColorConverter::startColorCapture);
        layout->addWidget(extractColorButton);

        // 创建用于存放颜色块和颜色输出的网格布局
        auto *colorBlockLayout = new QGridLayout();

        // 创建颜色输出
        screenColorOutput = new QLabel(this);
        screenColorOutput->setFixedSize(200, 90);
        screenColorOutput->setAlignment(Qt::AlignCenter);
        screenColorOutput->setStyleSheet("border: 1px solid #ddd");
        colorBlockLayout->addWidget(screenColorOutput, 0, 0); // 将颜色输出放在网格布局的左上角

        // 创建颜色块
        screenColorBlock = new QLabel(this);
        screenColorBlock->setFixedSize(30, 30); // 设置颜色块大小
        screenColorBlock->setStyleSheet("border: 1px solid #ddd");
        colorBlockLayout->addWidget(screenColorBlock, 0, 0, Qt::AlignTop | Qt::AlignRight); // 将颜色块放在颜色输出的右上角

        layout->addLayout(colorBlockLayout);

        setLayout(layout);

        installEventFilter(this); // 安装事件过滤器以捕获鼠标事件
    }

protected slots:

    void convertToHexColor() {
        // 从输入框获取颜色值
        QString colorText = colorInput->text();
        // 按逗号分隔RGB文本
        QStringList rgbValues = colorText.split(',');
        if (rgbValues.size() == 3) {
            // 获取R、G和B的值
            int red = rgbValues[0].toInt();
            int green = rgbValues[1].toInt();
            int blue = rgbValues[2].toInt();

            // 将RGB值转换为16进制字符串
            QString hexRed = QString("%1").arg(red, 2, 16, QChar('0')).toUpper();
            QString hexGreen = QString("%1").arg(green, 2, 16, QChar('0')).toUpper();
            QString hexBlue = QString("%1").arg(blue, 2, 16, QChar('0')).toUpper();

            // 构建16进制颜色代码文本
            QString hexText = QString("#%1%2%3").arg(hexRed).arg(hexGreen).arg(hexBlue);
            convertedColorOutput->setText(hexText);
        } else {
            // 处理无效颜色输入的情况
            convertedColorOutput->setText("Invalid color input");
        }
    }

    void convertToRgbColor() {
        // 从输入框获取颜色值
        QString colorText = colorInput->text();
        QColor color(colorText);
        if (color.isValid()) {
            // 获取16进制颜色码的红、绿、蓝通道值
            int red = color.red();
            int green = color.green();
            int blue = color.blue();
            // 构建RGB颜色代码文本
            QString outputText = QString("RGB(%1, %2, %3)").arg(red).arg(green).arg(blue);
            convertedColorOutput->setText(outputText);
        } else {
            // 处理无效颜色输入的情况
            convertedColorOutput->setText("Invalid color input");
        }
    }

    // 开始捕获颜色的槽函数
    void startColorCapture() {
        extractColorButton->setText("请开始移动鼠标 按Tab键终止取色");
        colorTimer->start();
    }

    void extractScreenColor() {
        QPoint cursorPos = QCursor::pos();
        QScreen *screen = QGuiApplication::screenAt(cursorPos);

        if (screen) {
            QPixmap screenshot = screen->grabWindow(0, cursorPos.x(), cursorPos.y(), 1, 1);
            if (!screenshot.isNull()) {
                QColor color = screenshot.toImage().pixel(0, 0);
                QString colorText = QString("Screen Color: #%1").arg(color.name().mid(1));
                screenColorOutput->setText(colorText);

                QString styleSheet = QString("background-color: %1; border: 1px solid #ddd;").arg(color.name());
                screenColorBlock->setStyleSheet(styleSheet);
            } else {
                screenColorOutput->setText("Failed to grab screen color");
            }
        } else {
            screenColorOutput->setText("No screen found at the cursor position");
        }
    }

    // 停止捕获颜色的槽函数
    void stopColorCapture() {
        colorTimer->stop();
        extractColorButton->setText("开始提取屏幕颜色");
    }
protected:
    // 捕获松开Tab按键事件
    bool eventFilter(QObject *watched, QEvent *event) override {
        if (event->type() == QEvent::WindowDeactivate || event->type() == QEvent::KeyRelease) {
            stopColorCapture();
            return true;
        }
        return QObject::eventFilter(watched, event);
    }

private:
    QLineEdit *colorInput;
    QPushButton *convertButton;
    QTextEdit *convertedColorOutput;
    QPushButton *extractColorButton;
    QLabel *screenColorOutput;
    QLabel *screenColorBlock;
    QTimer *colorTimer;
};

class Base64ImageConverter : public QWidget {
Q_OBJECT
public:
    explicit Base64ImageConverter(QWidget *parent = nullptr) : QWidget(parent) {
        auto *layout = new QVBoxLayout(this);

        selectImageButton = new QPushButton("选择图片", this);
        connect(selectImageButton, &QPushButton::clicked, this, &Base64ImageConverter::selectImage);
        layout->addWidget(selectImageButton);

        imagePathTextEdit = new QTextEdit(this);
        imagePathTextEdit->setReadOnly(true);
        layout->addWidget(imagePathTextEdit);

        convertToBase64Button = new QPushButton("转换为Base64编码", this);
        connect(convertToBase64Button, &QPushButton::clicked, this, &Base64ImageConverter::convertToBase64);
        layout->addWidget(convertToBase64Button);

        base64OutputTextEdit = new QTextEdit(this);
        base64OutputTextEdit->setAcceptRichText(false);
        layout->addWidget(base64OutputTextEdit);

        convertToImagePreviewButton = new QPushButton("Base64编码转图片预览", this);
        connect(convertToImagePreviewButton, &QPushButton::clicked, this, &Base64ImageConverter::convertToImagePreview);
        layout->addWidget(convertToImagePreviewButton);

        imagePreviewLabel = new QLabel(this);
        imagePreviewLabel->setFixedHeight(200); // 设置图片高度为 200
        layout->addWidget(imagePreviewLabel);

        setLayout(layout);
    }

private slots:

    void selectImage() {
        // 创建文件对话框用于选择图片文件
        QString imagePath = QFileDialog::getOpenFileName(this, tr("选择图片"), "", tr("Images (*.png *.jpg *.bmp)"));

        // 如果用户选择了图片文件,则显示文件路径
        if (!imagePath.isEmpty()) {
            imagePathTextEdit->setText(imagePath);
            selectedImagePath = imagePath;
        }
    }

    void convertToBase64() {
        if (selectedImagePath.isEmpty()) {
            QMessageBox::warning(this, "警告", "请先选择图片");
            return;
        }

        // 读取选定图片文件的内容
        QFile file(selectedImagePath);
        if (file.open(QIODevice::ReadOnly)) {
            QByteArray imageData = file.readAll();
            QString base64Data = imageData.toBase64();

            base64OutputTextEdit->setText(base64Data);
        } else {
            QMessageBox::critical(this, "错误", "无法读取图片文件");
        }
    }

    void convertToImagePreview() {
        QString base64Data = base64OutputTextEdit->toPlainText().toUtf8();

        if (base64Data.isEmpty()) {
            QMessageBox::warning(this, "警告", "请先转换为Base64编码");
            return;
        }

        // 从Base64数据创建QImage并显示在标签中
        QByteArray byteArray = QByteArray::fromBase64(base64Data.toUtf8());
        QImage image;
        image.loadFromData(byteArray);

        if (!image.isNull()) {
            // 水平居中对齐
            imagePreviewLabel->setAlignment(Qt::AlignHCenter);
            // 缩放图片到 200x200
            QPixmap pixmap = QPixmap::fromImage(image.scaled(200, 200, Qt::KeepAspectRatio));
            imagePreviewLabel->setPixmap(pixmap);
        } else {
            QMessageBox::critical(this, "错误", "无法加载图片");
        }
    }

private:
    QPushButton *selectImageButton;
    QTextEdit *imagePathTextEdit;
    QPushButton *convertToBase64Button;
    QTextEdit *base64OutputTextEdit;
    QPushButton *convertToImagePreviewButton;
    QLabel *imagePreviewLabel;
    QString selectedImagePath;
};

class Base64Converter : public QWidget {
Q_OBJECT
public:
    explicit Base64Converter(QWidget *parent = nullptr) : QWidget(parent) {
        auto *layout = new QVBoxLayout(this);

        inputTextEdit = new QTextEdit(this);
        layout->addWidget(inputTextEdit);

        encryptButton = new QPushButton("加密", this);
        connect(encryptButton, &QPushButton::clicked, this, &Base64Converter::encryptText);
        layout->addWidget(encryptButton);

        decryptButton = new QPushButton("解密", this);
        connect(decryptButton, &QPushButton::clicked, this, &Base64Converter::decryptText);
        layout->addWidget(decryptButton);

        outputTextEdit = new QTextEdit(this);
        outputTextEdit->setReadOnly(true);
        layout->addWidget(outputTextEdit);

        setLayout(layout);
    }

private slots:

    void encryptText() {
        QString inputText = inputTextEdit->toPlainText().toUtf8();
        QByteArray byteArray = inputText.toUtf8().toBase64();
        outputTextEdit->setText(byteArray);
    }

    void decryptText() {
        QString inputText = inputTextEdit->toPlainText();
        QByteArray byteArray = QByteArray::fromBase64(inputText.toUtf8());
        outputTextEdit->setText(byteArray);
    }

private:
    QTextEdit *inputTextEdit;
    QTextEdit *outputTextEdit;
    QPushButton *encryptButton;
    QPushButton *decryptButton;
};

class XmlFormatter : public QWidget {
Q_OBJECT
public:
    explicit XmlFormatter(QWidget *parent = nullptr) : QWidget(parent) {
        auto *layout = new QVBoxLayout(this);

        inputTextEdit = new QTextEdit(this);
        layout->addWidget(inputTextEdit);

        formatButton = new QPushButton("格式化 XML", this);
        connect(formatButton, &QPushButton::clicked, this, &XmlFormatter::formatXml);
        layout->addWidget(formatButton);

        outputTextEdit = new QTextEdit(this);
        outputTextEdit->setReadOnly(true);
        layout->addWidget(outputTextEdit);

        setLayout(layout);
    }

private slots:

    void formatXml() {
        // 获取输入的XML文本
        QString inputText = inputTextEdit->toPlainText();

        if (!inputText.isEmpty()) {
            // 使用 QXmlStreamReader 读取输入的 XML 文本
            QXmlStreamReader reader(inputText);
            QString formattedXml;

            int indentLevel = 0;
            while (!reader.atEnd() && !reader.hasError()) {
                if (reader.isStartElement()) {
                    formattedXml += getIndent(indentLevel) + "<" + reader.name().toString() + ">\n";
                    ++indentLevel;
                } else if (reader.isEndElement()) {
                    --indentLevel;
                    formattedXml += getIndent(indentLevel) + "</" + reader.name().toString() + ">\n";
                } else if (reader.isCharacters() && !reader.isWhitespace()) {
                    formattedXml += getIndent(indentLevel) + reader.text().toString() + "\n";
                }
                reader.readNext();
            }

            if (reader.hasError()) {
                outputTextEdit->setText("XML 解析错误:" + reader.errorString());
            } else {
                outputTextEdit->setText(formattedXml);
            }
        } else {
            // 如果输入为空,则清空输出区域
            outputTextEdit->clear();
        }
    }

    static QString getIndent(int level) {
        return QString(level * 4, ' '); // 4空格作为缩进
    }

private:
    QTextEdit *inputTextEdit;
    QPushButton *formatButton;
    QTextEdit *outputTextEdit;
};

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);

        auto *xmlFormatterButton = new QPushButton("显示XML格式化功能");
        xmlFormatterButton->setObjectName("xmlFormatterButton");
        connect(xmlFormatterButton, &QPushButton::clicked, this, &MyMainWindow::toggleXmlFormatter);
        xmlFormatter = new XmlFormatter(this);
        xmlFormatter->hide();
        layout->addWidget(xmlFormatter);
        layout->addWidget(xmlFormatterButton);

        auto *base64ConverterButton = new QPushButton("显示Base64加解密功能");
        base64ConverterButton->setObjectName("base64ConverterButton");
        connect(base64ConverterButton, &QPushButton::clicked, this, &MyMainWindow::toggleBase64Converter);
        base64Converter = new Base64Converter(this);
        base64Converter->hide();
        layout->addWidget(base64Converter);
        layout->addWidget(base64ConverterButton);

        auto *base64ImageConverterButton = new QPushButton("显示Base64图片预览功能");
        base64ImageConverterButton->setObjectName("base64ImageConverterButton");
        connect(base64ImageConverterButton, &QPushButton::clicked, this, &MyMainWindow::toggleBase64ImageConverter);
        base64ImageConverter = new Base64ImageConverter(this);
        base64ImageConverter->hide();
        layout->addWidget(base64ImageConverter);
        layout->addWidget(base64ImageConverterButton);

        auto *colorConverterButton = new QPushButton("显示色值提取转换功能");
        colorConverterButton->setObjectName("colorConverterButton");
        connect(colorConverterButton, &QPushButton::clicked, this, &MyMainWindow::toggleColorConverter);
        colorConverter = new ColorConverter(this);
        colorConverter->hide();
        layout->addWidget(colorConverter);
        layout->addWidget(colorConverterButton);

        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();
        }
    }

    void toggleXmlFormatter() {
        auto *curButton = findChild<QPushButton *>("xmlFormatterButton");
        if (xmlFormatter->isHidden()) {
            if (curButton) {
                curButton->setText("隐藏XML格式化");
            }
            xmlFormatter->show();
        } else {
            if (curButton) {
                curButton->setText("显示XML格式化");
            }
            xmlFormatter->hide();
        }
    }

    void toggleBase64Converter() {
        auto *curButton = findChild<QPushButton *>("base64ConverterButton");
        if (base64Converter->isHidden()) {
            if (curButton) {
                curButton->setText("隐藏Base64加解密功能");
            }
            base64Converter->show();
        } else {
            if (curButton) {
                curButton->setText("显示Base64加解密功能");
            }
            base64Converter->hide();
        }
    }

    void toggleBase64ImageConverter() {
        auto *curButton = findChild<QPushButton *>("base64ImageConverterButton");
        if (base64ImageConverter->isHidden()) {
            if (curButton) {
                curButton->setText("隐藏Base64图片预览功能");
            }
            base64ImageConverter->show();
        } else {
            if (curButton) {
                curButton->setText("显示Base64图片预览功能");
            }
            base64ImageConverter->hide();
        }
    }

    void toggleColorConverter() {
        auto *curButton = findChild<QPushButton *>("colorConverterButton");
        if (colorConverter->isHidden()) {
            if (curButton) {
                curButton->setText("隐藏色值提取转换功能");
            }
            colorConverter->show();
        } else {
            if (curButton) {
                curButton->setText("显示色值提取转换功能");
            }
            colorConverter->hide();
        }
    }

private:
    ClipboardManager *clipboardManager;
    JsonFormatter *jsonFormatter;
    DateTimeTimestampConverter *timestampConverter;
    NumberBaseConverter *numberBaseConverter;
    XmlFormatter *xmlFormatter;
    Base64Converter *base64Converter;
    Base64ImageConverter *base64ImageConverter;
    ColorConverter *colorConverter;
};

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    MyMainWindow mainWindow;
    mainWindow.show();

    return QApplication::exec();
}

#include "main.moc"

想要了解这个小工具是如何发展到现在这个地步的话,就看看往期文章吧~,记得要多跑一跑代码。如果大家有什么想要的功能或者想问的问题的话,就在评论区留言吧。Thanks♪(・ω・)ノ

往期文章一览

C++学习之路(一)什么是C++?如何循序渐进的学习C++?【纯干货】

C++学习之路(二)C++如何实现一个超简单的学生信息管理系统?C++示例和小项目实例

C++学习之路(三)解析讲解超简单学生信息管理系统代码知识点 - 《根据实例学知识》

C++学习之路(四)C++ 实现简单的待办事项列表命令行应用 - 示例代码拆分讲解

C++学习之路(五)C++ 实现简单的文件管理系统命令行应用 - 示例代码拆分讲解

C++学习之路(六)C++ 实现简单的工具箱系统命令行应用 - 示例代码拆分讲解

C++学习之路(七)C++ 实现简单的Qt界面(消息弹框、按钮点击事件监听)- 示例代码拆分讲解

C++学习之路(八)C++ 用Qt5实现一个工具箱(增加一个粘贴板记录管理功能)- 示例代码拆分讲解

C++学习之路(九)C++ 用Qt5实现一个工具箱(增加一个JSON数据格式化功能)- 示例代码拆分讲解

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

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

C++学习之路(十二)C++ 用Qt5实现一个工具箱(增加一个XML文本格式化功能)- 示例代码拆分讲解

C++学习之路(十三)C++ 用Qt5实现一个工具箱(增加一个Base64加解密功能)- 示例代码拆分讲解

C++学习之路(十四)C++ 用Qt5实现一个工具箱(增加一个Base64图片编码预览功能)- 示例代码拆分讲解


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

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

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

相关文章

Postman可以卸载了!这款IDEA插件太好用了!

Postman是大家最常用的API调试工具&#xff0c;那么有没有一种方法可以不用手动写入接口到Postman&#xff0c;即可进行接口调试操作&#xff1f;今天给大家推荐一款IDEA插件&#xff1a;Apipost Helper&#xff0c;写完代码就可以调试接口并一键生成接口文档&#xff01;而且还…

C++笔试题之回文数的判断

“回文”是指正读反读都能读通的句子&#xff0c;它是古今中外都有的一种修辞方式和文字游戏&#xff0c;如“我为人人&#xff0c;人人为我”等。在数学中也有这样一类数字有这样的特征&#xff0c;成为回文数&#xff08;palindrome number&#xff09;。 设n是一任意自然数…

vue3中使用antv-X6实现关系图

先看效果图&#xff1a; 1、安装 npm installantv/x6 --save 这里使用的X6中自定义节点的方式实现的&#xff0c;项目目录如下&#xff0c;hooks里面存放一些函数和变量 nodes里面是自定义节点的页面&#xff0c;最外围的index.vue就是主渲染页面 2、testSh/index.vue 注意&…

计算机视觉GPT时刻!UC伯克利三巨头祭出首个纯CV大模型,推理惊现AGI火花

计算机视觉的GPT时刻&#xff0c;来了&#xff01; 最近&#xff0c;来自UC伯克利的计算机视觉「三巨头」联手推出了第一个无自然语言的纯视觉大模型&#xff08;Large Vision Models&#xff09;&#xff0c;并且第一次证明了纯视觉模型本身也是可扩展的&#xff08;scalabil…

YOLOv8创新魔改教程(三)如何添加注意力机制注意力机制的用法与思考

注意力机制的用法与思考 好多同学问我加了CA注意力机制&#xff0c;CBAM注意力机制&#xff0c;都没有涨点&#xff0c;然后就在不停地换不同的注意力机制&#xff0c;其实并不是这样的。今天和大家讨论一下注意力机制的用法与思考。 &#xff08;一&#xff09;添加位置 大…

异常追踪与 JIRA 实现双向联动

前言 当应用程序或系统出现异常时&#xff0c;通常需要及时处理以保证系统的正常运行。通过异常追踪与 JIRA 双向联动&#xff0c;可以让企业内部相关人员快速了解、分析问题故障发生的原因、追溯并记录故障的处理过程&#xff0c;有效提高人员的沟通效率&#xff0c;极大降低…

使用 SVN 新建本地仓库和提交

在写代码的时候经常要看自己修改了什么或者临时备份一下&#xff0c;发现 SVN 比 Git 更好用&#xff0c;下面是使用 TortoiseSVN 在本地新建仓库和关联仓库的方法。 1. 新建文件夹&#xff0c;在文件夹里面右键选择 TortoiseSVN -> Create repository here 。 2. 选择建立…

C++红黑树封装set和map(很详细)

前言 在前面&#xff0c;我们学习了红黑树。&#xff08;没学过红黑树直接看会很吃力&#xff09;set和map的底层就是红黑树&#xff0c;现在我们要用这棵树来封装STL里面的容器&#xff1a;set和map。 下面是之前讲过的红黑树&#xff0c;他只是普通的“Key”模型,适合封装set…

排序:直接插入排序希尔排序

目录 排序&#xff1a; 概念&#xff1a; 直接插入排序&#xff1a; 代码的实现&#xff1a; 代码解析&#xff1a; 总结&#xff1a; 希尔排序&#xff1a; 代码实现&#xff1a; 预排序&#xff1a; 代码优化&#xff1a; gap 的 本质 &#xff1a; 直接…

千梦网创:设计一个100%回本赚钱的培训模式

互联网上搞培训&#xff0c;牌坊立的快&#xff0c;倒的也快。 你会的东西你教了才能赚钱&#xff0c;你想赚钱你就要教。 你只要教了&#xff0c;立马就有人模仿&#xff0c;立马就有人收费比你更低。 所以&#xff0c;你不会变&#xff0c;你没有核心的东西&#xff0c;就…

日本IT行业发展前景怎么样呢?

由于日本劳动力短缺&#xff0c;招聘外国IT工程师的公司越来越多&#xff0c;目前&#xff0c;日本IT行业有约28,000多名外国工程师&#xff0c;占所有日本IT工程师的3%。随着大量海外人才涌入日本&#xff0c;预计这一数字还会进一步增长&#xff0c;所以有不少人想要转行做赴…

RHCE作业

目录 1、搭建一个通过网址https://www.openlab.com/money访问的缴费网站&#xff0c;网站内容为money 2、配置DNS的正向解析 1、搭建一个通过网址https://www.openlab.com/money访问的缴费网站&#xff0c;网站内容为money 首先查看自己是不是有nginx的包没有的话装一个 首…

ModStartCMS v7.7.0 集成内容区块,文件选择顺序

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议&#xff0c;免费且不限制商业使用。 功能特性 丰富的模块市…

智能优化算法应用:基于鼠群算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于鼠群算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于鼠群算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.鼠群算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

mapbox系列:常见功能使用总结

前言 最近在写一个大屏的时候使用mapbox&#xff0c;将开发过程进行总结如下&#xff1a; 功能1&#xff1a;mapbox logo显示与隐藏 使用mapbox时地图上会有mapbox的logo&#xff0c;如下&#xff1a; 设置地图全局样式设置 :deep(.mapboxgl-ctrl) {display: none !import…

第十五届蓝桥杯模拟赛B组(第二期)C++

前言&#xff1a; 第一次做蓝桥模拟赛的博客记录&#xff0c;可能有很多不足的地方&#xff0c;现在将第十五届蓝桥杯模拟赛B组&#xff08;第二期&#xff09;的题目与代码与大家进行分享&#xff0c;我是用C做的&#xff0c;有好几道算法题当时自己做的也是一脸懵&#xff0c…

R语言学习

Part1阶段1&#xff1a;入门基础 1安装R和RStudio&#xff1a; 下载并安装R&#xff1a;https://cran.r-project.org/ 下载并安装RStudio&#xff1a;https://www.rstudio.com/products/rstudio/download/ 2Hello World&#xff1a; 学习如何在R中输出"Hello, World!"…

苹果OS X系统介绍(Mac OS --> Mac OS X --> OS X --> macOS)

文章目录 OS X系统介绍历史与版本架构内核与低级系统图形&#xff0c;媒体和用户界面应用程序和服务 特性用户友好强大的命令行安全性集成与互操作性 总结 OS X系统介绍 OS X是由苹果公司为Macintosh计算机系列设计的基于UNIX的操作系统。其界面友好&#xff0c;易于使用&…

论文阅读:Distributed Initialization for VIRO with Position-Unknown UWB Network

前言 Distributed Initialization for Visual-Inertial-Ranging Odometry with Position-Unknown UWB Network这篇论文是发表在ICRA 2023上的一篇文章&#xff0c;本文提出了一种基于位置未知UWB网络的一致性视觉惯性紧耦合优化测距算法( DC-VIRO )的分布式初始化方法。 对于…

【从删库到跑路 | MySQL数据库总结篇】JDBC编程

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【MySQL学习专栏】&#x1f388; 本专栏旨在分享学习MySQL的一点学习心得&#xff0c;欢迎大家在评论区讨论&#x1f48c; 目录 一、前言…