当前位置:

首页 > 编程开发 > 基于Qt的实用二维码生成解决方案

基于Qt的实用二维码生成解决方案

纯C++且无任何依赖的nayukiqrcode库最适合Qt项目集成二维码功能,通过QRCodeWidget类可方便实现生成、保存、添加Logo及自定义样式设置。该库轻量高效,无需额外配置。相比之下,QZXing和libqrencode因体积较大或需编译而推荐度较低。

本文目录

    在Qt项目中集成二维码生成功能,通常有几种主流选择。下面把各方案的优劣势摆出来,再结合集成难度和实际使用场景,给出一份靠谱的推荐。

    一、解决方案架构

    1.1 技术选型比较

    方案优点缺点推荐度
    qrcode (nayuki)纯C++, 轻量, 无依赖功能基础★★★★★
    QZXing功能强大, 支持多种格式体积大, 依赖多★★★★
    libqrencode性能好, 广泛使用需要额外编译★★★★
    ZXing-C++Google出品, 功能全编译复杂★★★

    推荐方案:qrcode (nayuki) - 最适合Qt集成

    基于Qt的实用二维码生成解决方案

    二、核心实现方案

    2.1 方案一:使用 qrcode (nayuki) - 推荐

    要说最轻量、最容易集成的方案,非它莫属。纯C++实现,没有任何外部依赖,直接扔进项目就能用。

    下载qrcode库

    # 下载qrcode库
    git clone https://github.com/nayuki/QR-Code-generator.git

    Qt项目集成

    文件结构:

    QRCodeDemo/

    ├── main.cpp

    ├── QRCodeWidget.h

    ├── QRCodeWidget.cpp

    ├── qrcode/

    │ ├── BitBuffer.hpp

    │ ├── QrCode.hpp

    │ ├── QrSegment.hpp

    │ └── README.md

    └── QRCodeDemo.pro

    QRCodeWidget.h:

    #ifndef QRCODEWIDGET_H
    #define QRCODEWIDGET_H
    #include 
    #include 
    #include 
    #include 
    #include 
    class QRCodeWidget : public QWidget
    {
        Q_OBJECT
    public:
        explicit QRCodeWidget(QWidget *parent = nullptr);
        // 生成二维码
        bool generateQRCode(const QString& text, 
                           int version = 5,  // 二维码版本(1-40)
                           int eccLevel = 1, // 纠错等级(0-3)
                           int border = 4);  // 边距
        // 获取二维码图片
        QImage getQRCodeImage() const { return m_qrCodeImage; }
        // 保存二维码图片
        bool sa veToFile(const QString& filename, 
                       int scale = 4,  // 缩放倍数
                       const QString& format = "PNG");
        // 设置样式
        void setForegroundColor(const QColor& color) { m_foregroundColor = color; }
        void setBackgroundColor(const QColor& color) { m_backgroundColor = color; }
        void setDrawStyle(bool rounded = false, bool useGradient = false);
        // 添加Logo
        bool addLogo(const QImage& logo, int logoSizePercentage = 20);
        // 二维码信息
        int getVersion() const { return m_version; }
        int getEccLevel() const { return m_eccLevel; }
        QString getEccLevelName() const;
        int getSize() const { return m_qrSize; }
    protected:
        void paintEvent(QPaintEvent *event) override;
    signals:
        void qrCodeGenerated(bool success, const QString& error = QString());
    private:
        // 绘制二维码
        void drawQRCode(QPainter& painter, int x, int y, int size);
        // 绘制Logo
        void drawLogo(QPainter& painter, int x, int y, int size);
        // 计算版本容量
        static int getMaxCapacity(int version, int eccLevel);
    private:
        QImage m_qrCodeImage;
        QImage m_logoImage;
        QColor m_foregroundColor = Qt::black;
        QColor m_backgroundColor = Qt::white;
        int m_version = 5;
        int m_eccLevel = 1;  // 1 = LOW, 0 = MEDIUM, 2 = QUARTILE, 3 = HIGH
        int m_border = 4;
        int m_qrSize = 0;
        bool m_roundedModules = false;
        bool m_useGradient = false;
        std::vector m_qrData;
    };
    #endif // QRCODEWIDGET_H

    QRCodeWidget.cpp:

    #include "QRCodeWidget.h"
    #include "qrcode/QrCode.hpp"
    #include 
    #include 
    #include 
    #include 
    #include 
    
    using qrcodegen::QrCode;
    using qrcodegen::QrSegment;
    
    QRCodeWidget::QRCodeWidget(QWidget *parent) 
        : QWidget(parent) {
        setMinimumSize(200, 200);
    }
    
    bool QRCodeWidget::generateQRCode(const QString& text, int version, int eccLevel, int border) {
        if (text.isEmpty()) {
            emit qrCodeGenerated(false, "文本不能为空");
            return false;
        }
        
        if (version < 1 || version > 40) {
            emit qrCodeGenerated(false, "版本必须在1-40之间");
            return false;
        }
        
        if (eccLevel < 0 || eccLevel > 3) {
            emit qrCodeGenerated(false, "纠错等级必须在0-3之间");
            return false;
        }
        
        m_version = version;
        m_eccLevel = eccLevel;
        m_border = border;
        
        try {
            // 将QString转换为UTF-8字节
            QByteArray utf8Data = text.toUtf8();
            std::vector data(utf8Data.begin(), utf8Data.end());
            
            // 创建QR码
            QrCode::Ecc ecc = static_cast(eccLevel);
            QrCode qr = QrCode::encodeBytes(data, ecc, version, version);
            
            m_qrSize = qr.getSize();
            m_qrData.clear();
            
            // 复制二维码数据
            for (int y = 0; y < m_qrSize; y++) {
                for (int x = 0; x < m_qrSize; x++) {
                    m_qrData.push_back(qr.getModule(x, y) ? 1 : 0);
                }
            }
            
            // 创建图片
            int imgSize = m_qrSize + 2 * m_border;
            m_qrCodeImage = QImage(imgSize, imgSize, QImage::Format_ARGB32);
            m_qrCodeImage.fill(m_backgroundColor);
            
            QPainter painter(&m_qrCodeImage);
            painter.setRenderHint(QPainter::Antialiasing);
            drawQRCode(painter, m_border, m_border, m_qrSize);
            
            // 如果有Logo,绘制Logo
            if (!m_logoImage.isNull()) {
                drawLogo(painter, m_border, m_border, m_qrSize);
            }
            
            painter.end();
            
            update();  // 触发重绘
            emit qrCodeGenerated(true);
            return true;
            
        } catch (const std::exception& e) {
            qWarning() << "生成二维码失败:" << e.what();
            emit qrCodeGenerated(false, QString("生成失败: %1").arg(e.what()));
            return false;
        }
    }
    
    void QRCodeWidget::drawQRCode(QPainter& painter, int x, int y, int size) {
        int moduleSize = size / m_qrSize;
        
        painter.setPen(Qt::NoPen);
        
        if (m_useGradient) {
            QLinearGradient gradient(x, y, x + size, y + size);
            gradient.setColorAt(0, m_foregroundColor);
            gradient.setColorAt(1, m_foregroundColor.darker(150));
            painter.setBrush(gradient);
        } else {
            painter.setBrush(m_foregroundColor);
        }
        
        for (int row = 0; row < m_qrSize; row++) {
            for (int col = 0; col < m_qrSize; col++) {
                if (m_qrData[row * m_qrSize + col]) {
                    int px = x + col * moduleSize;
                    int py = y + row * moduleSize;
                    
                    if (m_roundedModules) {
                        painter.drawRoundedRect(px, py, moduleSize, moduleSize, 
                                               moduleSize / 3, moduleSize / 3);
                    } else {
                        painter.drawRect(px, py, moduleSize, moduleSize);
                    }
                }
            }
        }
    }
    
    void QRCodeWidget::drawLogo(QPainter& painter, int x, int y, int size) {
        if (m_logoImage.isNull()) return;
        
        int logoSize = size * 0.2;  // Logo大小为二维码的20%
        int centerX = x + (size - logoSize) / 2;
        int centerY = y + (size - logoSize) / 2;
        
        QPixmap logoPixmap = QPixmap::fromImage(m_logoImage)
            .scaled(logoSize, logoSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
        
        // 绘制白色背景
        painter.setBrush(Qt::white);
        painter.setPen(Qt::NoPen);
        painter.drawRoundedRect(centerX - 2, centerY - 2, 
                               logoSize + 4, logoSize + 4, 8, 8);
        
        // 绘制Logo
        painter.drawPixmap(centerX, centerY, logoPixmap);
    }
    
    bool QRCodeWidget::sa veToFile(const QString& filename, int scale, const QString& format) {
        if (m_qrCodeImage.isNull()) {
            return false;
        }
        
        QImage scaledImage = m_qrCodeImage.scaled(
            m_qrCodeImage.width() * scale,
            m_qrCodeImage.height() * scale,
            Qt::KeepAspectRatio,
            Qt::SmoothTransformation
        );
        
        return scaledImage.sa ve(filename, format.toUpper().toUtf8());
    }
    
    void QRCodeWidget::setDrawStyle(bool rounded, bool useGradient) {
        m_roundedModules = rounded;
        m_useGradient = useGradient;
        update();
    }
    
    bool QRCodeWidget::addLogo(const QImage& logo, int logoSizePercentage) {
        if (logo.isNull()) {
            m_logoImage = QImage();
            return false;
        }
        
        m_logoImage = logo;
        update();
        return true;
    }
    
    QString QRCodeWidget::getEccLevelName() const {
        switch (m_eccLevel) {
        case 0: return "LOW (7%)";
        case 1: return "MEDIUM (15%)";
        case 2: return "QUARTILE (25%)";
        case 3: return "HIGH (30%)";
        default: return "UNKNOWN";
        }
    }
    
    int QRCodeWidget::getMaxCapacity(int version, int eccLevel) {
        // 简化的容量表(数字模式)
        static const int capacityTable[4][4] = {
            {17, 32, 53, 78},     // 版本1
            {32, 61, 100, 127},   // 版本2
            {53, 101, 165, 198},  // 版本3
            {78, 127, 198, 242}   // 版本4
        };
        
        if (version >= 1 && version <= 4 && eccLevel >= 0 && eccLevel <= 3) {
            return capacityTable[version-1][eccLevel];
        }
        return 0;
    }
    
    void QRCodeWidget::paintEvent(QPaintEvent *event) {
        Q_UNUSED(event);
        
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        
        if (!m_qrCodeImage.isNull()) {
            // 居中显示
            int x = (width() - m_qrCodeImage.width()) / 2;
            int y = (height() - m_qrCodeImage.height()) / 2;
            painter.drawImage(x, y, m_qrCodeImage);
        } else {
            // 显示提示
            painter.setPen(Qt::gray);
            painter.drawText(rect(), Qt::AlignCenter, "没有二维码数据");
        }
    }
    

    main.cpp:

    #include "MainWindow.h"
    #include 
    
    int main(int argc, char *argv[]) {
        QApplication app(argc, argv);
        
        // 设置应用程序信息
        app.setApplicationName("QR Code Generator");
        app.setOrganizationName("MyCompany");
        app.setApplicationVersion("1.0.0");
        
        MainWindow window;
        window.show();
        
        return app.exec();
    }
    

    2.2 方案二:使用QZXing库

    QZXing是Qt生态里功能比较全面的二维码处理库,不光能生成,还能解码,支持多种格式。

    安装QZXing

    # 方法1:通过vcpkg
    vcpkg install qzxing
    
    # 方法2:手动编译
    git clone https://github.com/ftylitak/qzxing.git
    cd qzxing
    mkdir build && cd build
    cmake ..
    make
    make install
    

    使用QZXing生成二维码

    // QZXingGenerator.h
    #ifndef QZXINGGENERATOR_H
    #define QZXINGGENERATOR_H
    
    #include 
    #include 
    #include 
    #include 
    
    class QZXingGenerator : public QObject
    {
        Q_OBJECT
        
    public:
        explicit QZXingGenerator(QObject *parent = nullptr);
        
        // 生成二维码
        QImage generateQRCode(const QString& data, 
                             const QSize& size = QSize(200, 200),
                             const QColor& foreground = Qt::black,
                             const QColor& background = Qt::white,
                             QZXing::EncoderCorrectionLevel correction = QZXing::EncodeErrorCorrectionLevel_M);
        
        // 生成带Logo的二维码
        QImage generateQRCodeWithLogo(const QString& data, 
                                     const QImage& logo,
                                     const QSize& size = QSize(200, 200));
        
        // 批量生成
        QList batchGenerate(const QStringList& dataList, 
                                   const QSize& size = QSize(200, 200));
        
        // 保存到文件
        bool sa veQRCode(const QString& data, 
                       const QString& filename,
                       const QSize& size = QSize(200, 200));
        
    signals:
        void generationComplete(const QImage& qrCode);
        void generationError(const QString& error);
        
    private:
        QZXing m_qzxing;
    };
    #endif // QZXINGGENERATOR_H
    
    // QZXingGenerator.cpp
    #include "QZXingGenerator.h"
    #include 
    #include 
    #include 
    
    QZXingGenerator::QZXingGenerator(QObject *parent) 
        : QObject(parent) {
        // 初始化QZXing
        m_qzxing.setDecoder(QZXing::DecoderFormat_QR_CODE);
    }
    
    QImage QZXingGenerator::generateQRCode(const QString& data, 
                                          const QSize& size,
                                          const QColor& foreground,
                                          const QColor& background,
                                          QZXing::EncoderCorrectionLevel correction) {
        if (data.isEmpty()) {
            emit generationError("数据不能为空");
            return QImage();
        }
        
        try {
            // 设置编码参数
            QZXing::EncodeErrorCorrectionLevel eccLevel = correction;
            
            // 生成二维码
            QImage qrCode = m_qzxing.encodeData(data, size, foreground, background, eccLevel);
            
            if (qrCode.isNull()) {
                emit generationError("生成二维码失败");
                return QImage();
            }
            
            emit generationComplete(qrCode);
            return qrCode;
            
        } catch (const std::exception& e) {
            emit generationError(QString("生成错误: %1").arg(e.what()));
            return QImage();
        }
    }
    
    QImage QZXingGenerator::generateQRCodeWithLogo(const QString& data, 
                                                  const QImage& logo,
                                                  const QSize& size) {
        // 先生成基本二维码
        QImage qrCode = generateQRCode(data, size);
        if (qrCode.isNull() || logo.isNull()) {
            return qrCode;
        }
        
        // 在二维码中心添加Logo
        QImage result = qrCode.copy();
        QPainter painter(&result);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setRenderHint(QPainter::SmoothPixmapTransform);
        
        // 计算Logo位置和大小
        int logoSize = qMin(size.width(), size.height()) * 0.2;  // Logo大小为20%
        int x = (size.width() - logoSize) / 2;
        int y = (size.height() - logoSize) / 2;
        
        // 绘制白色背景
        painter.setBrush(Qt::white);
        painter.setPen(Qt::NoPen);
        painter.drawRoundedRect(x-2, y-2, logoSize+4, logoSize+4, 5, 5);
        
        // 绘制Logo
        QPixmap scaledLogo = QPixmap::fromImage(logo)
            .scaled(logoSize, logoSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
        painter.drawPixmap(x, y, scaledLogo);
        
        return result;
    }
    
    QList QZXingGenerator::batchGenerate(const QStringList& dataList, 
                                                const QSize& size) {
        QList result;
        
        for (const QString& data : dataList) {
            QImage qrCode = generateQRCode(data, size);
            if (!qrCode.isNull()) {
                result.append(qrCode);
            }
        }
        
        return result;
    }
    
    bool QZXingGenerator::sa veQRCode(const QString& data, 
                                    const QString& filename,
                                    const QSize& size) {
        QImage qrCode = generateQRCode(data, size);
        if (qrCode.isNull()) {
            return false;
        }
        
        return qrCode.sa ve(filename);
    }
    

    2.3 方案三:使用libqrencode

    这是一款C语言写的二维码生成库,性能相当不错,在很多开源项目里都有它的身影。

    安装libqrencode

    # Ubuntu/Debian
    sudo apt-get install libqrencode-dev
    # macOS
    brew install qrencode
    # Windows (vcpkg)
    vcpkg install qrencode

    libqrencode封装

    // LibQRencodeWrapper.h
    #ifndef LIBQRENCODEWRAPPER_H
    #define LIBQRENCODEWRAPPER_H
    
    #include 
    #include 
    #include 
    
    class LibQRencodeWrapper
    {
    public:
        enum QRCorrectionLevel {
            QR_ECLEVEL_L = 0,  // 7% 纠错
            QR_ECLEVEL_M = 1,  // 15% 纠错
            QR_ECLEVEL_Q = 2,  // 25% 纠错
            QR_ECLEVEL_H = 3   // 30% 纠错
        };
        
        struct QRCodeOptions {
            int version = 0;           // 0 = 自动选择
            QRCorrectionLevel level = QR_ECLEVEL_M;
            int margin = 4;            // 边距
            int scale = 4;             // 缩放倍数
            bool caseSensitive = true; // 大小写敏感
        };
        
        static QImage generateQRCode(const QString& text, 
                                    const QRCodeOptions& options = QRCodeOptions());
        
        static QString getLibraryVersion();
        
        static int getMaxVersion() { return 40; }
        static int getMinVersion() { return 1; }
        
    private:
        static QRcode* encodeString(const QString& text, 
                                   const QRCodeOptions& options);
    };
    #endif // LIBQRENCODEWRAPPER_H
    
    // LibQRencodeWrapper.cpp
    #include "LibQRencodeWrapper.h"
    #include 
    #include 
    
    QImage LibQRencodeWrapper::generateQRCode(const QString& text, 
                                             const QRCodeOptions& options) {
        if (text.isEmpty()) {
            return QImage();
        }
        
        QRcode* qr = encodeString(text, options);
        if (!qr) {
            qWarning() << "Failed to generate QR code";
            return QImage();
        }
        
        // 计算图片大小
        int qrSize = qr->width;
        int imageSize = (qrSize + 2 * options.margin) * options.scale;
        
        QImage image(imageSize, imageSize, QImage::Format_ARGB32);
        image.fill(Qt::white);
        
        QPainter painter(&image);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setBrush(Qt::black);
        painter.setPen(Qt::NoPen);
        
        // 绘制二维码
        for (int y = 0; y < qrSize; y++) {
            for (int x = 0; x < qrSize; x++) {
                if (qr->data[y * qrSize + x] & 1) {
                    int px = (options.margin + x) * options.scale;
                    int py = (options.margin + y) * options.scale;
                    painter.drawRect(px, py, options.scale, options.scale);
                }
            }
        }
        
        painter.end();
        QRcode_free(qr);
        
        return image;
    }
    
    QRcode* LibQRencodeWrapper::encodeString(const QString& text, 
                                            const QRCodeOptions& options) {
        QRecLevel level = static_cast(options.level);
        QRecLevel* hint = options.caseSensitive ? QR_MODE_8 : QR_MODE_KANJI;
        
        QRcode* qr = nullptr;
        
        if (options.version > 0) {
            // 指定版本
            qr = QRcode_encodeString(text.toUtf8().constData(),
                                     options.version,
                                     level,
                                     hint,
                                     1);
        } else {
            // 自动选择版本
            qr = QRcode_encodeString(text.toUtf8().constData(),
                                     0,
                                     level,
                                     hint,
                                     1);
        }
        
        return qr;
    }
    
    QString LibQRencodeWrapper::getLibraryVersion() {
        return QString("libqrencode %1").arg(qrencode_version());
    }
    

    三、功能丰富的二维码生成器

    3.1 主窗口设计

    // MainWindow.h
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include 
    #include 
    #include "QRCodeWidget.h"
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
        
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
        
    private slots:
        void onGenerateClicked();
        void onSa veClicked();
        void onClearClicked();
        void onAddLogoClicked();
        void onRemoveLogoClicked();
        void onTextChanged();
        void onStyleChanged();
        void onQRCodeGenerated(bool success, const QString& error = QString());
        void onUpdatePreview();
        
    private:
        void setupUI();
        void setupConnections();
        void updateCapacityInfo();
        void loadSettings();
        void sa veSettings();
        
    private:
        Ui::MainWindow *ui;
        QRCodeWidget *m_qrCodeWidget;
        QImage m_logoImage;
        QTimer *m_previewTimer;
    };
    #endif // MAINWINDOW_H
    
    // MainWindow.cpp
    #include "MainWindow.h"
    #include "ui_MainWindow.h"
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
        , m_qrCodeWidget(new QRCodeWidget(this))
        , m_previewTimer(new QTimer(this)) {
        
        ui->setupUI(this);
        setupUI();
        setupConnections();
        loadSettings();
        
        m_previewTimer->setSingleShot(true);
        m_previewTimer->setInterval(500);  // 500ms延迟预览
    }
    
    MainWindow::~MainWindow() {
        sa veSettings();
        delete ui;
    }
    
    void MainWindow::setupUI() {
        // 设置中心窗口
        setCentralWidget(m_qrCodeWidget);
        
        // 创建工具栏
        QToolBar *toolBar = addToolBar("Main");
        toolBar->setMovable(false);
        
        toolBar->addAction("生成", this, &MainWindow::onGenerateClicked);
        toolBar->addAction("保存", this, &MainWindow::onSa veClicked);
        toolBar->addAction("清除", this, &MainWindow::onClearClicked);
        toolBar->addSeparator();
        toolBar->addAction("添加Logo", this, &MainWindow::onAddLogoClicked);
        toolBar->addAction("移除Logo", this, &MainWindow::onRemoveLogoClicked);
        
        // 创建状态栏
        statusBar()->showMessage("就绪");
        
        // 初始化控件
        for (int i = 1; i <= 10; i++) {
            ui->comboVersion->addItem(QString("V%1").arg(i), i);
        }
        ui->comboVersion->setCurrentIndex(4);  // 默认V5
        
        ui->comboECC->addItem("LOW (7%)", 0);
        ui->comboECC->addItem("MEDIUM (15%)", 1);
        ui->comboECC->addItem("QUARTILE (25%)", 2);
        ui->comboECC->addItem("HIGH (30%)", 3);
        ui->comboECC->setCurrentIndex(1);  // 默认MEDIUM
        
        ui->spinBorder->setValue(4);
        ui->spinScale->setValue(4);
        
        updateCapacityInfo();
    }
    
    void MainWindow::setupConnections() {
        connect(ui->btnGenerate, &QPushButton::clicked, 
                this, &MainWindow::onGenerateClicked);
        connect(ui->btnSa ve, &QPushButton::clicked, 
                this, &MainWindow::onSa veClicked);
        connect(ui->btnClear, &QPushButton::clicked, 
                this, &MainWindow::onClearClicked);
        connect(ui->btnAddLogo, &QPushButton::clicked, 
                this, &MainWindow::onAddLogoClicked);
        connect(ui->btnRemoveLogo, &QPushButton::clicked, 
                this, &MainWindow::onRemoveLogoClicked);
        connect(ui->textContent, &QTextEdit::textChanged, 
                this, &MainWindow::onTextChanged);
        connect(ui->checkRounded, &QCheckBox::toggled, 
                this, &MainWindow::onStyleChanged);
        connect(ui->checkGradient, &QCheckBox::toggled, 
                this, &MainWindow::onStyleChanged);
        connect(ui->btnCopy, &QPushButton::clicked,  {
            QApplication::clipboard()->setPixmap(
                QPixmap::fromImage(m_qrCodeWidget->getQRCodeImage())
            );
            statusBar()->showMessage("二维码已复制到剪贴板", 2000);
        });
        
        connect(m_qrCodeWidget, &QRCodeWidget::qrCodeGenerated,
                this, &MainWindow::onQRCodeGenerated);
        connect(m_previewTimer, &QTimer::timeout,
                this, &MainWindow::onUpdatePreview);
    }
    
    void MainWindow::onGenerateClicked() {
        QString text = ui->textContent->toPlainText().trimmed();
        if (text.isEmpty()) {
            QMessageBox::warning(this, "警告", "请输入要编码的内容");
            return;
        }
        
        int version = ui->comboVersion->currentData().toInt();
        int eccLevel = ui->comboECC->currentData().toInt();
        int border = ui->spinBorder->value();
        
        // 检查内容长度是否超过容量限制
        int maxCapacity = m_qrCodeWidget->getMaxCapacity(version, eccLevel);
        if (text.length() > maxCapacity) {
            QMessageBox::warning(this, "警告", 
                QString("内容过长!最大容量为%1字符,当前%2字符")
                .arg(maxCapacity).arg(text.length()));
            return;
        }
        
        statusBar()->showMessage("正在生成二维码...");
        m_qrCodeWidget->generateQRCode(text, version, eccLevel, border);
    }
    
    void MainWindow::onSa veClicked() {
        if (m_qrCodeWidget->getQRCodeImage().isNull()) {
            QMessageBox::warning(this, "警告", "没有可保存的二维码");
            return;
        }
        
        QString filter = "PNG 图片 (*.png);;JPEG 图片 (*.jpg *.jpeg);;BMP 图片 (*.bmp)";
        QString filename = QFileDialog::getSa veFileName(this, "保存二维码", 
                                                       "qrcode.png", filter);
        
        if (!filename.isEmpty()) {
            int scale = ui->spinScale->value();
            QString format = QFileInfo(filename).suffix().toUpper();
            
            if (m_qrCodeWidget->sa veToFile(filename, scale, format)) {
                statusBar()->showMessage(QString("保存成功: %1").arg(filename), 3000);
            } else {
                QMessageBox::critical(this, "错误", "保存失败");
            }
        }
    }
    
    void MainWindow::onClearClicked() {
        ui->textContent->clear();
        m_qrCodeWidget->addLogo(QImage());  // 移除Logo
        statusBar()->showMessage("已清除", 2000);
    }
    
    void MainWindow::onAddLogoClicked() {
        QString filename = QFileDialog::getOpenFileName(this, "选择Logo图片", 
                                                       "", 
                                                       "图片文件 (*.png *.jpg *.jpeg *.bmp)");
        if (!filename.isEmpty()) {
            m_logoImage.load(filename);
            if (m_logoImage.isNull()) {
                QMessageBox::warning(this, "警告", "无法加载图片");
                return;
            }
            
            m_qrCodeWidget->addLogo(m_logoImage, ui->spinLogoSize->value());
            statusBar()->showMessage("Logo已添加", 2000);
        }
    }
    
    void MainWindow::onRemoveLogoClicked() {
        m_logoImage = QImage();
        m_qrCodeWidget->addLogo(QImage());  // 移除Logo
        statusBar()->showMessage("Logo已移除", 2000);
    }
    
    void MainWindow::onTextChanged() {
        // 延迟预览
        m_previewTimer->start();
        updateCapacityInfo();
    }
    
    void MainWindow::onStyleChanged() {
        bool rounded = ui->checkRounded->isChecked();
        bool gradient = ui->checkGradient->isChecked();
        m_qrCodeWidget->setDrawStyle(rounded, gradient);
    }
    
    void MainWindow::onQRCodeGenerated(bool success, const QString& error) {
        if (success) {
            QString info = QString("版本: V%1, 纠错: %2, 尺寸: %3×%3")
                .arg(m_qrCodeWidget->getVersion())
                .arg(m_qrCodeWidget->getEccLevelName())
                .arg(m_qrCodeWidget->getSize());
            statusBar()->showMessage(info);
        } else {
            QMessageBox::critical(this, "错误", error);
            statusBar()->showMessage("生成失败");
        }
    }
    
    void MainWindow::onUpdatePreview() {
        if (ui->checkAutoPreview->isChecked()) {
            onGenerateClicked();
        }
    }
    
    void MainWindow::updateCapacityInfo() {
        int version = ui->comboVersion->currentData().toInt();
        int eccLevel = ui->comboECC->currentData().toInt();
        int currentLength = ui->textContent->toPlainText().length();
        int maxCapacity = m_qrCodeWidget->getMaxCapacity(version, eccLevel);
        
        QString info = QString("长度: %1 / %2").arg(currentLength).arg(maxCapacity);
        ui->labelCapacity->setText(info);
        
        // 进度条显示
        int percent = qMin(100, (currentLength * 100) / maxCapacity);
        ui->progressCapacity->setValue(percent);
        
        // 颜色指示
        if (percent > 90) {
            ui->progressCapacity->setStyleSheet("QProgressBar::chunk { background-color: red; }");
        } else if (percent > 70) {
            ui->progressCapacity->setStyleSheet("QProgressBar::chunk { background-color: orange; }");
        } else {
            ui->progressCapacity->setStyleSheet("");
        }
    }
    
    void MainWindow::loadSettings() {
        QSettings settings;
        
        // 加载窗口位置和大小
        if (settings.contains("geometry")) {
            restoreGeometry(settings.value("geometry").toByteArray());
        }
        
        // 加载上次的内容
        QString lastContent = settings.value("lastContent").toString();
        if (!lastContent.isEmpty()) {
            ui->textContent->setPlainText(lastContent);
        }
    }
    
    void MainWindow::sa veSettings() {
        QSettings settings;
        
        // 保存窗口位置和大小
        settings.setValue("geometry", sa veGeometry());
        
        // 保存当前内容
        settings.setValue("lastContent", ui->textContent->toPlainText());
    }
    

    3.2 UI界面设计 (ui_MainWindow.h)

    // UI设计文件 (通过Qt Designer创建)
    #ifndef UI_MAINWINDOW_H
    #define UI_MAINWINDOW_H
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    class Ui_MainWindow {
    public:
        QWidget *centralWidget;
        QVBoxLayout *verticalLayout;
        QHBoxLayout *horizontalLayout;
        QVBoxLayout *leftLayout;
        QTextEdit *textContent;
        QHBoxLayout *buttonLayout;
        QPushButton *btnGenerate;
        QPushButton *btnSa ve;
        QPushButton *btnClear;
        QPushButton *btnCopy;
        QVBoxLayout *rightLayout;
        QGroupBox *groupSettings;
        QVBoxLayout *settingsLayout;
        QHBoxLayout *layoutVersion;
        QLabel *labelVersion;
        QComboBox *comboVersion;
        QHBoxLayout *layoutECC;
        QLabel *labelECC;
        QComboBox *comboECC;
        QHBoxLayout *layoutBorder;
        QLabel *labelBorder;
        QSpinBox *spinBorder;
        QHBoxLayout *layoutScale;
        QLabel *labelScale;
        QSpinBox *spinScale;
        QHBoxLayout *layoutLogo;
        QLabel *labelLogo;
        QSpinBox *spinLogoSize;
        QPushButton *btnAddLogo;
        QPushButton *btnRemoveLogo;
        QGroupBox *groupStyle;
        QVBoxLayout *styleLayout;
        QCheckBox *checkRounded;
        QCheckBox *checkGradient;
        QCheckBox *checkAutoPreview;
        QGroupBox *groupInfo;
        QVBoxLayout *infoLayout;
        QLabel *labelCapacity;
        QProgressBar *progressCapacity;
        
        void setupUI(QMainWindow *MainWindow) {
            if (MainWindow->objectName().isEmpty())
                MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
            MainWindow->resize(800, 600);
            
            centralWidget = new QWidget(MainWindow);
            centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
            
            verticalLayout = new QVBoxLayout(centralWidget);
            verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
            
            horizontalLayout = new QHBoxLayout();
            horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
            
            // 左侧:输入区域
            leftLayout = new QVBoxLayout();
            leftLayout->setObjectName(QString::fromUtf8("leftLayout"));
            
            textContent = new QTextEdit(centralWidget);
            textContent->setObjectName(QString::fromUtf8("textContent"));
            textContent->setPlaceholderText("请输入要编码的内容...");
            leftLayout->addWidget(textContent);
            
            buttonLayout = new QHBoxLayout();
            buttonLayout->setObjectName(QString::fromUtf8("buttonLayout"));
            
            btnGenerate = new QPushButton(centralWidget);
            btnGenerate->setObjectName(QString::fromUtf8("btnGenerate"));
            btnGenerate->setText("生成二维码");
            buttonLayout->addWidget(btnGenerate);
            
            btnSa ve = new QPushButton(centralWidget);
            btnSa ve->setObjectName(QString::fromUtf8("btnSa ve"));
            btnSa ve->setText("保存");
            buttonLayout->addWidget(btnSa ve);
            
            btnClear = new QPushButton(centralWidget);
            btnClear->setObjectName(QString::fromUtf8("btnClear"));
            btnClear->setText("清除");
            buttonLayout->addWidget(btnClear);
            
            btnCopy = new QPushButton(centralWidget);
            btnCopy->setObjectName(QString::fromUtf8("btnCopy"));
            btnCopy->setText("复制");
            buttonLayout->addWidget(btnCopy);
            
            leftLayout->addLayout(buttonLayout);
            horizontalLayout->addLayout(leftLayout, 2);
            
            // 右侧:设置区域
            rightLayout = new QVBoxLayout();
            rightLayout->setObjectName(QString::fromUtf8("rightLayout"));
            
            // 设置组
            groupSettings = new QGroupBox(centralWidget);
            groupSettings->setObjectName(QString::fromUtf8("groupSettings"));
            groupSettings->setTitle("设置");
            settingsLayout = new QVBoxLayout(groupSettings);
            
            // 版本
            layoutVersion = new QHBoxLayout();
            labelVersion = new QLabel(groupSettings);
            labelVersion->setText("版本:");
            layoutVersion->addWidget(labelVersion);
            
            comboVersion = new QComboBox(groupSettings);
            layoutVersion->addWidget(comboVersion);
            settingsLayout->addLayout(layoutVersion);
            
            // 纠错等级
            layoutECC = new QHBoxLayout();
            labelECC = new QLabel(groupSettings);
            labelECC->setText("纠错等级:");
            layoutECC->addWidget(labelECC);
            
            comboECC = new QComboBox(groupSettings);
            layoutECC->addWidget(comboECC);
            settingsLayout->addLayout(layoutECC);
            
            // 边距
            layoutBorder = new QHBoxLayout();
            labelBorder = new QLabel(groupSettings);
            labelBorder->setText("边距:");
            layoutBorder->addWidget(labelBorder);
            
            spinBorder = new QSpinBox(groupSettings);
            spinBorder->setRange(0, 20);
            spinBorder->setValue(4);
            layoutBorder->addWidget(spinBorder);
            settingsLayout->addLayout(layoutBorder);
            
            // 缩放
            layoutScale = new QHBoxLayout();
            labelScale = new QLabel(groupSettings);
            labelScale->setText("保存缩放:");
            layoutScale->addWidget(labelScale);
            
            spinScale = new QSpinBox(groupSettings);
            spinScale->setRange(1, 10);
            spinScale->setValue(4);
            layoutScale->addWidget(spinScale);
            settingsLayout->addLayout(layoutScale);
            
            // Logo设置
            layoutLogo = new QHBoxLayout();
            labelLogo = new QLabel(groupSettings);
            labelLogo->setText("Logo大小:");
            layoutLogo->addWidget(labelLogo);
            
            spinLogoSize = new QSpinBox(groupSettings);
            spinLogoSize->setRange(5, 50);
            spinLogoSize->setValue(20);
            spinLogoSize->setSuffix("%");
            layoutLogo->addWidget(spinLogoSize);
            
            btnAddLogo = new QPushButton(groupSettings);
            btnAddLogo->setText("添加");
            layoutLogo->addWidget(btnAddLogo);
            
            btnRemoveLogo = new QPushButton(groupSettings);
            btnRemoveLogo->setText("移除");
            layoutLogo->addWidget(btnRemoveLogo);
            settingsLayout->addLayout(layoutLogo);
            
            rightLayout->addWidget(groupSettings);
            
            // 样式组
            groupStyle = new QGroupBox(centralWidget);
            groupStyle->setObjectName(QString::fromUtf8("groupStyle"));
            groupStyle->setTitle("样式");
            styleLayout = new QVBoxLayout(groupStyle);
            
            checkRounded = new QCheckBox(groupStyle);
            checkRounded->setText("圆角模块");
            styleLayout->addWidget(checkRounded);
            
            checkGradient = new QCheckBox(groupStyle);
            checkGradient->setText("渐变颜色");
            styleLayout->addWidget(checkGradient);
            
            checkAutoPreview = new QCheckBox(groupStyle);
            checkAutoPreview->setText("实时预览");
            styleLayout->addWidget(checkAutoPreview);
            
            rightLayout->addWidget(groupStyle);
            
            // 信息组
            groupInfo = new QGroupBox(centralWidget);
            groupInfo->setObjectName(QString::fromUtf8("groupInfo"));
            groupInfo->setTitle("信息");
            infoLayout = new QVBoxLayout(groupInfo);
            
            labelCapacity = new QLabel(groupInfo);
            labelCapacity->setText("长度: 0/0");
            infoLayout->addWidget(labelCapacity);
            
            progressCapacity = new QProgressBar(groupInfo);
            progressCapacity->setRange(0, 100);
            infoLayout->addWidget(progressCapacity);
            
            rightLayout->addWidget(groupInfo);
            rightLayout->addStretch();
            
            horizontalLayout->addLayout(rightLayout, 1);
            verticalLayout->addLayout(horizontalLayout);
            
            MainWindow->setCentralWidget(centralWidget);
        }
    };
    #endif // UI_MAINWINDOW_H
    

    四、高级功能扩展

    4.1 批量生成工具

    // BatchQRCodeGenerator.h
    #ifndef BATCHQRCODEGENERATOR_H
    #define BATCHQRCODEGENERATOR_H
    
    #include 
    #include 
    #include 
    #include 
    
    class BatchQRCodeGenerator : public QObject, public QRunnable
    {
        Q_OBJECT
        
    public:
        struct BatchItem {
            QString id;
            QString content;
            QString filename;
            int version = 5;
            int eccLevel = 1;
            int scale = 4;
        };
        
        explicit BatchQRCodeGenerator(QObject *parent = nullptr);
        
        void addBatch(const QList& items);
        void clear();
        
        void run() override;
        
        void setOutputDir(const QString& dir) { m_outputDir = dir; }
        void setThreadCount(int count);
        
    signals:
        void progress(int current, int total, const QString& id);
        void finished(int successCount, int failedCount);
        void error(const QString& id, const QString& error);
        
    private:
        QList m_items;
        QString m_outputDir;
        QThreadPool m_threadPool;
    };
    #endif // BATCHQRCODEGENERATOR_H
    

    4.2 二维码解码功能

    // QRCodeDecoder.h
    #ifndef QRCODEDECODER_H
    #define QRCODEDECODER_H
    
    #include 
    #include 
    #include 
    
    class QRCodeDecoder : public QObject
    {
        Q_OBJECT
        
    public:
        explicit QRCodeDecoder(QObject *parent = nullptr);
        
        // 从图片文件解码
        QString decodeFromFile(const QString& filename);
        
        // 从QImage解码
        QString decodeFromImage(const QImage& image);
        
        // 从剪贴板解码
        QString decodeFromClipboard();
        
        // 从摄像头捕获
        void startCameraCapture();
        void stopCameraCapture();
        
    signals:
        void decoded(const QString& result);
        void cameraFrameCaptured(const QImage& frame);
        
    private:
        QZXing m_decoder;
    };
    #endif // QRCODEDECODER_H
    

    4.3 样式化二维码

    // StyledQRCodeGenerator.h
    #ifndef STYLEDQRCODEGENERATOR_H
    #define STYLEDQRCODEGENERATOR_H
    
    #include 
    
    class StyledQRCodeGenerator
    {
    public:
        enum PatternStyle {
            StyleDefault,
            StyleDots,
            StyleRounded,
            StyleStars,
            StyleHearts
        };
        
        struct StyleOptions {
            PatternStyle patternStyle = StyleDefault;
            QColor primaryColor = Qt::black;
            QColor secondaryColor = Qt::white;
            QColor gradientStart = Qt::black;
            QColor gradientEnd = Qt::darkGray;
            bool useGradient = false;
            int cornerRadius = 5;
        };
        
        static QImage generateStyledQRCode(const QString& text, 
                                          const QSize& size,
                                          const StyleOptions& options);
        
    private:
        static void applyPattern(QImage& image, const QImage& pattern, 
                                const QColor& color, int moduleSize);
        static QImage createDotPattern(int size);
        static QImage createStarPattern(int size);
        static QImage createHeartPattern(int size);
    };
    #endif // STYLEDQRCODEGENERATOR_H
    

    五、项目配置

    5.1 CMakeLists.txt

    cmake_minimum_required(VERSION 3.16)
    project(QRCodeGenerator)
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    # 查找Qt
    find_package(Qt6 COMPONENTS Core Widgets REQUIRED)
    # 包含目录
    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/qrcode)
    # 源文件
    set(SOURCES
        main.cpp
        QRCodeWidget.cpp
        MainWindow.cpp
        QRCodeGenerator.cpp
    )
    # 头文件
    set(HEADERS
        QRCodeWidget.h
        MainWindow.h
        QRCodeGenerator.h
    )
    # UI文件
    set(FORMS
        MainWindow.ui
    )
    # 资源文件
    set(RESOURCES
        resources.qrc
    )
    # 生成MOC文件
    qt6_wrap_cpp(MOC_SOURCES ${HEADERS})
    qt6_wrap_ui(UI_SOURCES ${FORMS})
    qt6_add_resources(RES_SOURCES ${RESOURCES})
    # 可执行文件
    add_executable(${PROJECT_NAME}
        ${SOURCES}
        ${MOC_SOURCES}
        ${UI_SOURCES}
        ${RES_SOURCES}
    )
    # 链接库
    target_link_libraries(${PROJECT_NAME}
        Qt6::Core
        Qt6::Widgets
    )

    5.2 .pro 文件 (qmake)

    # QRCodeGenerator.pro
    QT       += core gui
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    TARGET = QRCodeGenerator
    TEMPLATE = app
    # 源文件
    SOURCES += 
        main.cpp 
        QRCodeWidget.cpp 
        MainWindow.cpp
    HEADERS += 
        QRCodeWidget.h 
        MainWindow.h
    FORMS += 
        MainWindow.ui
    # 包含qrcode库
    INCLUDEPATH += $$PWD/qrcode
    # 编译选项
    QMAKE_CXXFLAGS += -std=c++17
    CONFIG += c++17
    # 发布配置
    CONFIG(release, debug|release) {
        DEFINES += QT_NO_DEBUG_OUTPUT
        QMAKE_CXXFLAGS += -O2
    }
    # 调试配置
    CONFIG(debug, debug|release) {
        DEFINES += QT_DEBUG
        QMAKE_CXXFLAGS += -g
    }

    5.3 资源文件

    
    
        
            
            icons/app.png
            icons/generate.png
            icons/sa ve.png
            icons/clear.png
            icons/logo.png
            
            styles/style.qss
            
            logo/default.png
        
    
    /* styles/style.qss */
    QMainWindow {
        background-color: #f5f5f5;
    }
    QGroupBox {
        font-weight: bold;
        border: 1px solid #ccc;
        border-radius: 5px;
        margin-top: 10px;
        padding-top: 10px;
    }
    QGroupBox::title {
        subcontrol-origin: margin;
        left: 10px;
        padding: 0 5px 0 5px;
    }
    QPushButton {
        padding: 8px 16px;
        border-radius: 4px;
        font-weight: bold;
    }
    QPushButton:hover {
        background-color: #e0e0e0;
    }
    QTextEdit {
        border: 1px solid #ccc;
        border-radius: 4px;
        padding: 8px;
        font-family: "Microsoft YaHei", "SimSun";
    }
    QProgressBar {
        border: 1px solid #ccc;
        border-radius: 4px;
        text-align: center;
    }
    QProgressBar::chunk {
        background-color: #4CAF50;
        border-radius: 4px;
    }

    六、使用示例

    6.1 基本使用

    #include "QRCodeGenerator.h"
    #include 
    #include 
    
    int main(int argc, char *argv[]) {
        QApplication app(argc, argv);
        
        // 创建二维码生成器
        QRCodeGenerator generator;
        
        // 生成基本二维码
        QImage qrCode = generator.generateQRCode("https://www.example.com", 
                                                QSize(200, 200));
        
        if (!qrCode.isNull()) {
            // 保存到文件
            qrCode.sa ve("qrcode.png");
            
            // 显示二维码
            QLabel label;
            label.setPixmap(QPixmap::fromImage(qrCode));
            label.show();
            
            return app.exec();
        }
        
        return 0;
    }
    

    6.2 高级功能

    // 高级使用示例
    void advancedExample() {
        QRCodeGenerator generator;
        
        // 1. 生成带Logo的二维码
        QImage logo(":/logo/company.png");
        QImage qrWithLogo = generator.generateQRCodeWithLogo(
            "https://www.company.com", logo, QSize(300, 300));
        
        // 2. 生成样式化二维码
        StyledQRCodeGenerator::StyleOptions options;
        options.patternStyle = StyledQRCodeGenerator::StyleDots;
        options.useGradient = true;
        options.gradientStart = QColor("#FF5722");
        options.gradientEnd = QColor("#FF9800");
        
        QImage styledQR = generator.generateStyledQRCode(
            "特殊样式", QSize(250, 250), options);
        
        // 3. 批量生成
        QList items;
        for (int i = 0; i < 10; i++) {
            BatchQRCodeGenerator::BatchItem item;
            item.id = QString("QR%1").arg(i+1);
            item.content = QString("https://example.com/item/%1").arg(i+1);
            item.filename = QString("qrcode_%1.png").arg(i+1);
            items.append(item);
        }
        
        BatchQRCodeGenerator batchGenerator;
        batchGenerator.addBatch(items);
        batchGenerator.setOutputDir("./qrcodes");
        
        QObject::connect(&batchGenerator, &BatchQRCodeGenerator::progress,
            int current, int total, const QString& id {
                qDebug() << "进度:" << current << "/" << total << id;
            });
        
        batchGenerator.run();
    }
    

    6.3 命令行工具

    // QRCodeCLI.cpp - 命令行工具
    #include "QRCodeGenerator.h"
    #include 
    #include 
    #include 
    
    int main(int argc, char *argv[]) {
        QCoreApplication app(argc, argv);
        app.setApplicationName("QR Code CLI");
        app.setApplicationVersion("1.0.0");
        
        QCommandLineParser parser;
        parser.setApplicationDescription("命令行二维码生成器");
        parser.addHelpOption();
        parser.addVersionOption();
        
        // 定义参数
        parser.addPositionalArgument("content", "要编码的内容");
        parser.addPositionalArgument("output", "输出文件", "[output.png]");
        
        QCommandLineOption sizeOption("s", "图片大小", "size", "200");
        parser.addOption(sizeOption);
        
        QCommandLineOption versionOption("v", "二维码版本", "version", "5");
        parser.addOption(versionOption);
        
        QCommandLineOption eccOption("e", "纠错等级", "ecc", "1");
        parser.addOption(eccOption);
        
        QCommandLineOption logoOption("l", "Logo文件", "logo");
        parser.addOption(logoOption);
        
        parser.process(app);
        
        // 获取参数
        QStringList args = parser.positionalArguments();
        if (args.isEmpty()) {
            parser.showHelp(1);
        }
        
        QString content = args.at(0);
        QString output = args.value(1, "qrcode.png");
        int size = parser.value(sizeOption).toInt();
        int version = parser.value(versionOption).toInt();
        int ecc = parser.value(eccOption).toInt();
        QString logoFile = parser.value(logoOption);
        
        // 生成二维码
        QRCodeGenerator generator;
        QImage qrCode;
        
        if (!logoFile.isEmpty()) {
            QImage logo(logoFile);
            if (logo.isNull()) {
                qCritical() << "无法加载Logo文件:" << logoFile;
                return 1;
            }
            qrCode = generator.generateQRCodeWithLogo(content, logo, QSize(size, size));
        } else {
            qrCode = generator.generateQRCode(content, QSize(size, size), version, ecc);
        }
        
        if (qrCode.isNull()) {
            qCritical() << "生成二维码失败";
            return 1;
        }
        
        if (qrCode.sa ve(output)) {
            qInfo() << "二维码已保存到:" << output;
            return 0;
        } else {
            qCritical() << "保存失败:" << output;
            return 1;
        }
    }
    
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 解决方案
    相关文章 更多
    加州大学圣地亚哥分校找到世界模型为何会
    加州大学圣地亚哥分校找到世界模型为何会"说谎"的答案和解决方案

    加州大学圣地亚哥分校研究发现世界模型产生幻觉的根源是训练数据覆盖不足,归纳为感知幻觉、动作边缘化幻觉和场景发散幻觉三类,并提出三种预测信号及覆盖感知训练、针对性数据收集两种干预方案。

    行业首发「3+N」批量部署行业解决方案亮相WRC 2026
    行业首发「3+N」批量部署行业解决方案亮相WRC 2026

    WRC 2026 乐聚「3+N」全场景实干方案亮相2026年8月20日,世界机器人大会(WRC)于北京盛大开幕。乐聚机器人此次带来了行业首发的全栈国产化「3 + N」批量部署行业解决方案,其展台更是本届展会中唯一能实现全场景、全自主、全天候机器人不停机作业的。该展台展示内容涵盖科研、商服、工业三大领

    跨越异构鸿沟,Redis迁移同步过程中的挑战与解决方案
    跨越异构鸿沟,Redis迁移同步过程中的挑战与解决方案

    随着云计算十余年的高速发展,作为目前可见的最新阶段,多云正在快步大踏步前进。而多云趋势所带来得数据云间迁移,也逐步常态化。因此,缓存 Redis 已成为高并发场景下提升数据访问速度的标配。不仅是数据云间迁移,目前大型系统对于缓存强依赖,致使大多数企业都会面临大量并发读写数据时访问速度慢、数据库压力大

    云原生全链路灰度发布:阿里云MSE+ZadigX解决方案
    云原生全链路灰度发布:阿里云MSE+ZadigX解决方案

    01、企业发布现状痛点目前企业在选择和实施发布策略时面临以下困境:缺乏云原生能力:由于从传统部署转变为云原生模式后,技术架构改造需要具备相关能力的人才。这使得企业在发布策略方面难以入手。缺乏自动化平台支持:即使找到适合产品现状的发布策略,仍然依赖手工逐步执行。这可能导致流程遗漏或人工操作失误,造成生

    破解器官移植供体短缺难题,组织器官生物制造未来将提供解决方案
    破解器官移植供体短缺难题,组织器官生物制造未来将提供解决方案

    杨华勇院士等专家探讨组织器官生物制造前沿进展。我国发明专利和科研产出居世界前列,骨科植入物等已进入临床。预计未来5-6年功能性皮肤、15-20年大型脏器、30年复杂器官有望临床应用。AI赋能与伦理问题引发关注。

    南芯科技亮相慕展:高端消费全场景端到端解决方案
    南芯科技亮相慕展:高端消费全场景端到端解决方案

    南芯科技在2026慕尼黑上海电子展展出高端消费电子、汽车电子等产品线,覆盖AI眼镜、机器人、智能手机、笔记本电脑、电视、可穿戴及移动电源等领域,提供从电源管理到电机控制的端到端解决方案。

    广立微打造3D IC 良率解决方案 助力韬定律生态发展
    广立微打造3D IC 良率解决方案 助力韬定律生态发展

    后摩尔时代,韬定律通过逻辑折叠、超细间距混合键合与TSV多层堆叠提升芯片性能,但面临键合缺陷、晶圆参数失配及DFT测试效率瓶颈。广立微打造涵盖DFM仿真、高速电性测试、AI晶圆配对及3D专用DFT的全链路国产方案,助力3DIC规模化量产。

    Torna 1.35.6 & 2.1.20 发布,接口文档解决方案
    Torna 1.35.6 & 2.1.20 发布,接口文档解决方案

    Torna1.35.6与2.1.20版本发布,优化单值返回结果展示逻辑,修复接口名称为空时Tab标签消失问题,新增点击接口名称跳转预览页面,改进Markdown渲染。Torna是一款接口文档管理工具,支持多人协同编辑、多源文档统一归档,扩展了Swagger的易用性与集成性。

    iPhone15软件删不掉怎么办?快速解决应用无法删除问题
    iPhone15软件删不掉怎么办?快速解决应用无法删除问题

    遇到iPhone15上的应用删不掉?别急,可以先强制重启设备,或者查查是不是屏幕使用时间给限制了。如果这俩办法都行不通,那么通过电脑上的iTunes(Windows)或Finder(Mac)来恢复系统,通常是解决问题的终极方案。 iPhone15应用删除失败的原因分析 你的iPhone15突然“挽留

    盘毂动力宣布推出轴向磁通电机全场景电驱解决方案
    盘毂动力宣布推出轴向磁通电机全场景电驱解决方案

    盘毂动力在TMC2026上宣布全球率先实现轴向磁通电机稳定规模化量产。该电机有效功率密度达25.73kW/kg,扭矩密度41.2N·m/kg,超92.5%工况效率达92.5%以上。产品覆盖9大产业赛道、100余类场景,销往30多国,并推出面向新能源车的全场景电驱方案,同等性能下减重超30%。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。