基于Qt,调用千问7B大模型,实现智能对话

之前在工作中,没有接触过大模型,只是经常使用AI来解决问题。

换工作之后,前几天看了同事做的一个系统,集成大模型,将AI应用到了工作中,当时第一感觉是,我是不是落后了一个世纪。。。

于是从他们的只言片语中,去查阅相关资料,因为我对Qt比较熟悉,因此基于Qt,做了一个简单的智能模型对话框。

一 大模型部署

  1. 硬件配置要求(建议按着自己电脑配置来)
    • 通义千问提供多种规格的模型版本,用户需根据硬件条件选择适配方案:
    • - 轻量级场景:Qwen3-4B模型仅需4GB显存,适合普通家用电脑。
    • - 中端场景:Qwen3-7B模型需8GB显存,可处理复杂逻辑推理任务。
    • - 高性能场景:Qwen3-14B及以上版本需16GB显存,支持多模态交互与专业领域应用。
    二、Ollama框架部署方案
  2. Ollama安装与配置
    • - 下载安装:访问Ollama官网下载对应系统版本,默认安装路径为C盘。
    • - 路径修改:可以通过ollama软件左侧settings,进行路径设置。如下图红色标注2对应所示

除此之外,上图中1对应的是是否联网;3对应的文本长度;4对应的是飞行模式

• - 模型下载:在命令行输入ollama pull qwen3:4b(以4B版本为例),等待下载完成。

二 大模型运行

使用win+r打开:运行窗口

输入cmd,回车,弹出命令行窗口

在窗口中输入以下代码:

bash 复制代码
ollama list

回车,显示已安装模型

继续输入需要运行的模型,我的是qwen7b,输入的是

bash 复制代码
ollama run qwen2.5:7b

回车,等待,此时可通过任务管理器查看ollama.exe的内存占用情况,等稳定后,说明启动成功,或者出现下图所示,也说明启动成功。

三 Qt案例编写

核心是访问大模型,主要是callQwenModel函数部分,直接上代码,不废话了,代码中关键部分有注释。经过测试,能和大模型进行通话,但是有一个bug,就是代码中设置的格式,无法在前端进行展示,在网上找了一些解决办法,但是都没用,如果有人能够解决,欢迎不吝赐教,在评论中指导一下,在此先感谢了。

mainwindow.cpp

bash 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkRequest>
#include <QJsonDocument>
#include <QJsonArray>
#include <QScrollBar>
#include <QDebug>



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

    //设置窗口属性
    setWindowTitle("千问7B聊天助手1.0");

    //连接网络请求完成信号
    connect(networkManager, &QNetworkAccessManager::finished, this, &MainWindow::onNetworkReply);

    ui->sendBtn->setEnabled(true);
    ui->inputEdit->setFocus();
    ui->sendBtn->setShortcut(QKeySequence(Qt::Key_Return));

    addMessage("你好,我是基于千问7B模型的AI助手,很高兴为你服务。", false);


}

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

void MainWindow::on_sendBtn_clicked()
{
    QString userInput = ui->inputEdit->text().trimmed();
    if(userInput.isEmpty())
    {
        return;
    }
    addMessage(userInput, true);

    ui->sendBtn->setEnabled(false);
    ui->inputEdit->clear();

    callQwenModel(userInput);
}

void MainWindow::onNetworkReply(QNetworkReply *reply)
{
    //重新启用发送按钮
    ui->sendBtn->setEnabled(true);


    if(reply->error() != QNetworkReply::NoError)
    {
        addMessage("请求出错:" + reply->errorString(), false);
        reply->deleteLater();
        return;
    }

    //读取响应
    QByteArray responseData = reply->readAll();
    reply->deleteLater();


    //解析JSON响应
    QJsonDocument doc = QJsonDocument::fromJson(responseData);
    if(!doc.isObject())
    {
        addMessage("响应解析失败", false);
        return;
    }

    QJsonObject jsonRes = doc.object();
    if(jsonRes.contains("response"))
    {
        QString resText = jsonRes["response"].toString();
        addMessage(resText, false);
    }
    else {
        addMessage("未找到响应", false);
    }
}

void MainWindow::addMessage(const QString &message, bool isUser)
{
    QString formattedMessage;
    if(isUser)
    {
        // 清除之前文本的格式
        QTextCursor cursor = ui->chatArea->textCursor();
        cursor.movePosition(QTextCursor::End);
//        formattedMessage = "<div style='margin: 10px; padding: 10px; background-color: rgb(255, 0, 0); border-radius: 10px; text-align: right;'>";
        formattedMessage = "<div style='margin: 10px; padding: 10px; background-color: rgb(255, 0, 0); border-radius: 10px; text-align: left;'>";
        formattedMessage += "<b>你:</b><br>" + message.toHtmlEscaped();

    }
    else {
        formattedMessage = "<div style='margin: 10px; padding: 10px; background-color: rgb(49, 255, 224); border-radius: 10px; text-align: left;'>";
        formattedMessage += "<b>AI助手:</b><br>" + message;

    }

        formattedMessage += "</div>";

    ui->chatArea->append(formattedMessage);

    QScrollBar *scrollbar = ui->chatArea->verticalScrollBar();
    scrollbar->setValue(scrollbar->maximum());
}

void MainWindow::callQwenModel(const QString &prompt)
{
    //ollama api 地址(假设使用默认配置
    QUrl url("http://localhost:11434/api/generate");


    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    //构造请求数据
    QJsonObject requesData;
    requesData["model"] = "qwen2.5:7b";     //对应的大模型名称
    requesData["prompt"] = prompt;
    requesData["stream"] = false;

    QJsonDocument doc(requesData);
    QByteArray data = doc.toJson();

    //发送post请求
    networkManager->post(request, data);
}

mainwindow.h

bash 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QJsonObject>


namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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




private slots:
    void on_sendBtn_clicked();
    void onNetworkReply(QNetworkReply *reply);



private:
    Ui::MainWindow *ui;
    QNetworkAccessManager *networkManager;

    void addMessage(const QString &message, bool isUser);
    void callQwenModel(const QString &prompt);
};

#endif // MAINWINDOW_H

pro文件

bash 复制代码
#-------------------------------------------------
#
# Project created by QtCreator 2025-11-16T09:38:49
#
#-------------------------------------------------

QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = LLM_test1
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

CONFIG += c++11

SOURCES += \
        main.cpp \
        mainwindow.cpp

HEADERS += \
        mainwindow.h

FORMS += \
        mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

main.cpp

bash 复制代码
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.ui

(根据以下文件在designer中进行设计)

bash 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>600</width>
    <height>500</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>千问7b聊天助手</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QLabel" name="label">
      <property name="styleSheet">
       <string notr="true">font-size: 16px; font-weight: bold; padding: 10px;</string>
      </property>
      <property name="text">
       <string>千问7B聊天助手</string>
      </property>
      <property name="alignment">
       <set>Qt::AlignCenter</set>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QTextEdit" name="chatArea">
      <property name="styleSheet">
       <string notr="true"/>
      </property>
      <property name="readOnly">
       <bool>true</bool>
      </property>
     </widget>
    </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <widget class="QLineEdit" name="inputEdit">
        <property name="styleSheet">
         <string notr="true">padding: 8px; border: 1px solid #ccc; border-radius: 5px;</string>
        </property>
        <property name="placeholderText">
         <string>请输入你的问题...</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="sendBtn">
        <property name="styleSheet">
         <string notr="true">padding: 8px 16px;
 background-color: #2196F3; 
color: white; 
border: none; 
border-radius: 5px;</string>
        </property>
        <property name="text">
         <string>发送</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>600</width>
     <height>23</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

运行结果截图

相关推荐
LiLiYuan.2 小时前
Arrays类和List接口的关联
java·开发语言·windows·python
武子康3 小时前
Java-170 Neo4j 事务、索引与约束实战:语法、并发陷阱与速修清单
java·开发语言·数据库·sql·nosql·neo4j·索引
7澄13 小时前
Java 实战:投票统计系统(HashMap 应用)
java·开发语言·intellij-idea·交互·控制台·hashmap
zzzsde3 小时前
【C++】红黑树:使用及实现
开发语言·c++·算法
点云SLAM3 小时前
C++ 中的栈(Stack)数据结构与堆的区别与内存布局(Stack vs Heap)
开发语言·数据结构·c++·内存布局·栈数据结构·c++标准算法·heap内存分配
枫子有风3 小时前
【go.sixue.work】2.2 面向对象:接口与多态
开发语言·后端·golang·xcode
qq_401700414 小时前
QT的5种标准对话框
开发语言·qt
智者知已应修善业5 小时前
【给定英文字符串统计最多小写最前输出】2023-2-27
c语言·开发语言·c++·经验分享·笔记·算法
我的golang之路果然有问题5 小时前
mac配置 unity+vscode的坑
开发语言·笔记·vscode·macos·unity·游戏引擎