基于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>

运行结果截图

相关推荐
小七-七牛开发者1 天前
论文解读:DeepSeek DSpark 在真实高并发推理服务中,如何保证 Token 生成又好又快?
ai·大模型·编程·ai coding
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner2 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
fengliaoai3 天前
DeepSeek搞了个DSpark,AI直接进入“秒回时代”,你还在傻等?
大模型
aqi004 天前
15天学会AI应用开发(九)利用Chroma持久化向量数据
人工智能·python·大模型·ai编程·ai应用
Quz7 天前
QML Hello World 入门示例
qt
aqi0010 天前
15天学会AI应用开发(八)使用向量数据库实现RAG功能
人工智能·python·大模型·ai编程·ai应用
xcyxiner10 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt