AIGC标识 全国产信创环境开发(二)--- 路线选型及AI开发安装使用

以下笔记是本人开发时的工作笔记,鸣谢仓颉编程语言交流群6中的xffish 、仓颉程序员和王总,谢谢您们的无私帮助。

 

一、开发基础部分:

  操作系统openEuler,桌面环境Kiran Desktop,数据库openGauss,后端开发语言仓颉,前端GUI是CJ-tauri。(因为仓颉并没有自己官方的前端GUI,选择了CJQT,退而求其次的话可以选Qt。)

二、开发工具部分:

  AI开发工具:TRAE CN      下载地址:https://www.trae.cn/ide/download  (仓颉推荐使用码道,但码道未能提供openEuler下的RPM版本,所以选择TRAE。)

  仓颉SDK:STS Version  1.2.0    下载地址:https://cangjie-lang.cn/download/1.2.0    (LTS Version 1.0.5  存在问题, STS 1.2.0此问题已修复。) 

      1、解压文件包,并将cangjie文件夹剪切到 /home/work/tools目录下。
    2、在work目录下显示隐藏文件,找到.bashrc文件,在文件最后一行添加  source /home/work/tools/cangjie/envsetup.sh

  开发基础组件安装:

    1、仓颉stdx组件 
      终端执行       bash -c "$(curl -fsSL https://raw.gitcode.com/Cangjie/cangjie_stdx/raw/main/downloader.sh)" -- 1.2.0.1 -p linux-aarch64 -d ./tools           X86_64:       bash -c "$(curl -fsSL https://raw.gitcode.com/Cangjie/cangjie_stdx/raw/main/downloader.sh)" -- 1.2.0.1 -p linux-x64 -d ./tools 
      重命名下载下来的文件夹为  stdx
      在work目录下显示隐藏文件,找到.bashrc文件,在文件最后一行添加    export CANGJIE_STDX=/home/work/tools/stdx  

    2、安装GUI开发缺失的工具包
      sudo dnf install -y gcc-c++ cmake make qt5-qtbase-devel libxkbcommon-x11

    3、克隆CJQT    (终端执行   cd ~/tools && git clone https://gitcode.com/Cangjie-TPC/CJQT.git && cd CJQT      )

  修正CJQT项目文件

     1、修改/home/work/tools/CJQT/native/includes/gui/gui_application.h  将其替换为如下内容

#ifndef CJ_GUI_APPLICATION_H
#define CJ_GUI_APPLICATION_H

#include <QGuiApplication>

class CjGuiApplication : public QGuiApplication
{
public:
    CjGuiApplication(int &argc, char **argv)
        : QGuiApplication(argc, argv)
    {
    }
};

#endif

    2、修改/home/work/tools/CJQT/native/includes/gui/paint_device.h  将其替换为如下内容

#ifndef CJ_PAINT_DEVICE_H
#define CJ_PAINT_DEVICE_H

#include <QPaintDevice>
#include <QPaintEngine>

class CjPaintDevice : public QPaintDevice
{
public:
    CjPaintDevice() {}

protected:
    QPaintEngine *paintEngine() const override
    {
        return nullptr;
    }
};

#endif // CJ_PAINT_DEVICE_H

   3、修改/home/work/tools/CJQT/native/includes/widgets/abstract_graphics_shape_item.h  将其替换为如下内容

#ifndef CJ_ABSTRACT_GRAPHICS_SHAPE_ITEM_H
#define CJ_ABSTRACT_GRAPHICS_SHAPE_ITEM_H

#include <QAbstractGraphicsShapeItem>
#include <QPainter>
#include <QStyleOptionGraphicsItem>

class CjAbstractGraphicsShapeItem : public QAbstractGraphicsShapeItem
{
public:
    explicit CjAbstractGraphicsShapeItem(QGraphicsItem *parent = nullptr)
        : QAbstractGraphicsShapeItem(parent) {}

    QRectF boundingRect() const override;
    void paint(QPainter *painter,
               const QStyleOptionGraphicsItem *option,
               QWidget *widget = nullptr) override;
};

#endif // CJ_ABSTRACT_GRAPHICS_SHAPE_ITEM_H

   4、修改/home/work/tools/CJQT/native/includes/widgets/application.h   将其替换为如下内容

#ifndef CJ_APPLICATION_H
#define CJ_APPLICATION_H

class Config;   // 前置声明:指针足够,不需要完整定义

#ifdef __cplusplus
extern "C" {
#endif

// 仅声明;定义在 application.cpp 中(否则多重定义)
extern Config *appConfig;

void nativeApplicationInit();

#ifdef __cplusplus
}
#endif

#endif // CJ_APPLICATION_H

   5、修改/home/work/tools/CJQT/native/includes/widgets/graphics_item.h   将其替换为如下内容

#ifndef CJ_GRAPHICS_ITEM_H
#define CJ_GRAPHICS_ITEM_H

#include <QGraphicsItem>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include <QGraphicsSceneContextMenuEvent>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsSceneWheelEvent>

class CjGraphicsItem : public QGraphicsItem
{
public:
    explicit CjGraphicsItem(QGraphicsItem *parent = nullptr);

    QRectF boundingRect() const override;
    void paint(QPainter *painter,
               const QStyleOptionGraphicsItem *option,
               QWidget *widget) override;

    // 绑定层入口:设置外接矩形(内部自动触发重绘)
    void setBoundingRect(const QRectF &rect);

    // 事件转发入口:基类对应函数是 protected,extern "C" 绑定层无法直接调用。
    // 注意:这里不带 QGraphicsItem:: 限定,走虚派发——
    // 子类重写了事件函数时走子类版本,未重写时落到基类默认实现
    void doContextMenuEvent(QGraphicsSceneContextMenuEvent *event)
    { contextMenuEvent(event); }

    void doMouseMoveEvent(QGraphicsSceneMouseEvent *event)
    { mouseMoveEvent(event); }

    void doMousePressEvent(QGraphicsSceneMouseEvent *event)
    { mousePressEvent(event); }

    void doMouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    { mouseReleaseEvent(event); }

    void doWheelEvent(QGraphicsSceneWheelEvent *event)
    { wheelEvent(event); }

private:
    QRectF m_boundingRect;
};

#endif // CJ_GRAPHICS_ITEM_H

   6、 修改 /home/work/tools/CJQT/native/src/widgets/graphics_view.cpp 文件,在#include "graphics_view.h"下面补充上如下引用     

#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QPainterPath>
#include <QBrush>
#include <QPoint>
#include <QPointF>
#include <QRect>
#include <QRectF>
#include <QPolygon>
#include <QPolygonF>
#include <QTransform>
#include <QPainter>

    7、修改/home/work/tools/CJQT/native/src/widgets/header_view.cpp 文件,找到   delete instance;   大约在16行,在下面添加  “   return 0;   ”

    8、修改/home/work/tools/CJQT/native/src/widgets/abstract_graphics_shape_item.cpp  文件,将uintptr_t nativeAbstractGraphicsShapeItemCreate(uintptr_t parentPtr) 函数内容改为如下

1 uintptr_t nativeAbstractGraphicsShapeItemCreate(uintptr_t parentPtr)
2     {
3         QGraphicsItem *parent = reinterpret_cast<QGraphicsItem *>(parentPtr);
4         CjAbstractGraphicsShapeItem *item = new CjAbstractGraphicsShapeItem(parent);
5         return reinterpret_cast<uintptr_t>(item);
6     }

 

    9、修改/home/work/tools/CJQT/native/src/widgets/tree_view.cpp 文件,32行     qDebug()<<"hide ok!!!"<<endl;    的<<endl 删掉 改为  qDebug()<<"hide ok!!!";

     10、修改/home/work/tools/CJQT/native/src/core/abstract_item_model.cpp 文件,17行 和 27行的<<endl 删掉

     11、修改/home/work/tools/CJQT/native/src/core/item_selection_model.cpp 文件,13行 的<<endl 删掉

     12、修改/home/work/tools/CJQT/native/src/gui/standard_item_model.cpp 文件,(nativeStandardItemModelRemoveColumn) 约67行 75行  82行 89行  下面添加   return 0;

     13、修改/home/work/tools/CJQT/native/src/gui/standard_item.cpp  文件,   在 uintptr_t nativeStandardItemCreateRC(int rows,int columns)  函数内添加两句  QStandardItem *item = new QStandardItem();       return reinterpret_cast<uintptr_t>(item);

     14、修改/home/work/tools/CJQT/native/src/gui/gui_application.cpp 文件修改为如下内容

#include "gui_application.h"
#include <QGuiApplication>
#include <QScreen>
#include <QDebug>

// QGuiApplication 构造要求 argc 是左值引用,且 argv 在应用整个生命周期内有效,
// 因此使用静态伪造参数,绑定层调用时无需传递 argc/argv。
static int fakeArgc = 1;
static char fakeArgv0[] = "cjqt";
static char *fakeArgv[] = { fakeArgv0, nullptr };

extern "C"
{
    uintptr_t nativeGuiApplicationCreate()
    {
        CjGuiApplication *app = new CjGuiApplication(fakeArgc, fakeArgv);
        return reinterpret_cast<uintptr_t>(app);
    }

    void nativeGuiApplicationDelete(uintptr_t ptr)
    {
        CjGuiApplication *instance = reinterpret_cast<CjGuiApplication *>(ptr);
        delete instance;
    }

    int nativeGuiApplicationExec(uintptr_t ptr)
    {
        CjGuiApplication *instance = reinterpret_cast<CjGuiApplication *>(ptr);
        return instance->exec();
    }

    void nativeGuiApplicationQuit()
    {
        // quit 是静态槽,不需要实例指针
        QGuiApplication::quit();
    }

    uintptr_t nativeGuiApplicationPrimaryScreen()
    {
        qDebug() << "nativeGuiApplicationPrimaryScreen";
        QScreen *screen = QGuiApplication::primaryScreen();
        if (screen == nullptr) {
            qWarning() << "nativeGuiApplicationPrimaryScreen: no screen, "
                          "请确认已先调用 nativeGuiApplicationCreate()";
            return 0;
        }
        qDebug() << "primaryScreen:" << screen->name();
        return reinterpret_cast<uintptr_t>(screen);
    }
}

    15、修改/home/work/tools/CJQT/native/src/widgets/application.cpp   文件修改为如下内容

#include "application.h"
#include "config.h"        // Config 完整定义,按你项目实际路径写
#include <QApplication>

// 全局变量唯一一处定义(配合头文件中的 extern 声明)
Config *appConfig = nullptr;

namespace
{
    void register_meta_types()
    {
        qRegisterMetaType<QVector<int>>();
    }
}

extern "C"
{
    void nativeApplicationInit()
    {
        register_meta_types();
        appConfig = new Config();
        appConfig->appInit = true;
    }

    void nativeApplicationInitWithArg(int argc, char *argv[])
    {
        register_meta_types();
        appConfig = new Config();
        appConfig->appInit = true;
        appConfig->argc = argc;
        appConfig->argv = argv;
        // 注意:QApplication 后续会读取 argv,argv 指向的内存
        // 必须在整个应用生命周期内保持有效
    }

    bool nativeApplicationIsCreate()
    {
        return appConfig != nullptr && appConfig->app != nullptr;
    }

    bool nativeApplicationExec()
    {
        if (appConfig != nullptr && appConfig->app != nullptr)
        {
            return appConfig->app->exec();
        }
        return false;
    }

    void nativeApplicationBeep()
    {
        if (appConfig != nullptr && appConfig->app != nullptr)
        {
            appConfig->app->beep();
        }
    }

    uintptr_t nativeApplicationPrimaryScreen()
    {
        if (appConfig != nullptr && appConfig->app != nullptr)
        {
            return reinterpret_cast<uintptr_t>(appConfig->app->primaryScreen());
        }
        return 0;
    }

    void nativeApplicationQuit()
    {
        if (appConfig != nullptr && appConfig->app != nullptr)
        {
            appConfig->app->quit();
        }
    }

    void nativeApplicationDelete()
    {
        if (appConfig != nullptr)
        {
            if (appConfig->app != nullptr)
            {
                delete appConfig->app;   // 先删 Qt 应用对象
                appConfig->app = nullptr;
            }
            delete appConfig;            // 再删配置对象
            appConfig = nullptr;         // 置空,防悬挂指针被复用
        }
    }
}

    16、修改/home/work/tools/CJQT/native/src/widgets/graphics_item.cpp 文件修改为如下内容

#include "graphics_item.h"

CjGraphicsItem::CjGraphicsItem(QGraphicsItem *parent)
    : QGraphicsItem(parent)
    , m_boundingRect(0.0, 0.0, 0.0, 0.0)
{
}

QRectF CjGraphicsItem::boundingRect() const
{
    return m_boundingRect;
}

void CjGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(painter);
    Q_UNUSED(option);
    Q_UNUSED(widget);
    // 占位:通用图元默认不绘制内容。
    // 具体形状子类(矩形/椭圆等)必须重写本函数绘制真实图形
}

void CjGraphicsItem::setBoundingRect(const QRectF &rect)
{
    if (rect == m_boundingRect)
        return;
    prepareGeometryChange(); // 几何变化前必须调用,否则重绘区域错乱、留下残影
    m_boundingRect = rect;
}

extern "C"
{
    uintptr_t nativeGraphicsItemCreate(uintptr_t parentPtr)
    {
        if (parentPtr == 0L)
        {
            CjGraphicsItem *item = new CjGraphicsItem();
            return reinterpret_cast<uintptr_t>(item);
        }
        QGraphicsItem *parent = reinterpret_cast<QGraphicsItem *>(static_cast<uintptr_t>(parentPtr));
        CjGraphicsItem *item = new CjGraphicsItem(parent);
        return reinterpret_cast<uintptr_t>(item);
    }

    void nativeGraphicsItemDelete(uintptr_t ptr)
    {
        CjGraphicsItem *instance = reinterpret_cast<CjGraphicsItem *>(static_cast<uintptr_t>(ptr));
        if (instance == nullptr)
            return;
        // 所有权规则:加入场景后归场景管。先移出场景再 delete,
        // 否则场景析构时会再删一遍,双重释放崩溃
        if (instance->scene() != nullptr)
            instance->scene()->removeItem(instance);
        delete instance;
    }

    void nativeGraphicsItemSetBoundingRect(uintptr_t ptr,
                                           double x, double y,
                                           double width, double height)
    {
        CjGraphicsItem *instance = reinterpret_cast<CjGraphicsItem *>(static_cast<uintptr_t>(ptr));
        if (instance != nullptr)
            instance->setBoundingRect(QRectF(x, y, width, height));
    }

    void nativeGraphicsItemDoContextMenuEvent(uintptr_t ptr, uintptr_t eventPtr)
    {
        CjGraphicsItem *instance = reinterpret_cast<CjGraphicsItem *>(static_cast<uintptr_t>(ptr));
        QGraphicsSceneContextMenuEvent *event =
            reinterpret_cast<QGraphicsSceneContextMenuEvent *>(static_cast<uintptr_t>(eventPtr));
        if (instance != nullptr && event != nullptr)
            instance->doContextMenuEvent(event);
    }

    void nativeGraphicsItemDoMouseMoveEvent(uintptr_t ptr, uintptr_t eventPtr)
    {
        CjGraphicsItem *instance = reinterpret_cast<CjGraphicsItem *>(static_cast<uintptr_t>(ptr));
        QGraphicsSceneMouseEvent *event =
            reinterpret_cast<QGraphicsSceneMouseEvent *>(static_cast<uintptr_t>(eventPtr));
        if (instance != nullptr && event != nullptr)
            instance->doMouseMoveEvent(event);
    }

    void nativeGraphicsItemDoMousePressEvent(uintptr_t ptr, uintptr_t eventPtr)
    {
        CjGraphicsItem *instance = reinterpret_cast<CjGraphicsItem *>(static_cast<uintptr_t>(ptr));
        QGraphicsSceneMouseEvent *event =
            reinterpret_cast<QGraphicsSceneMouseEvent *>(static_cast<uintptr_t>(eventPtr));
        if (instance != nullptr && event != nullptr)
            instance->doMousePressEvent(event);
    }

    void nativeGraphicsItemDoMouseReleaseEvent(uintptr_t ptr, uintptr_t eventPtr)
    {
        CjGraphicsItem *instance = reinterpret_cast<CjGraphicsItem *>(static_cast<uintptr_t>(ptr));
        QGraphicsSceneMouseEvent *event =
            reinterpret_cast<QGraphicsSceneMouseEvent *>(static_cast<uintptr_t>(eventPtr));
        if (instance != nullptr && event != nullptr)
            instance->doMouseReleaseEvent(event);
    }

    void nativeGraphicsItemDoWheelEvent(uintptr_t ptr, uintptr_t eventPtr)
    {
        CjGraphicsItem *instance = reinterpret_cast<CjGraphicsItem *>(static_cast<uintptr_t>(ptr));
        QGraphicsSceneWheelEvent *event =
            reinterpret_cast<QGraphicsSceneWheelEvent *>(static_cast<uintptr_t>(eventPtr));
        if (instance != nullptr && event != nullptr)
            instance->doWheelEvent(event);
    }
}

 

       13、用系统 Qt 编译 native 桥 
      cd native && mkdir -p build && cd build      #完成修改后应该全程无错。
      unset QT_HOME # 防止残留值干扰
      QT_HOME=/usr cmake .. -DCMAKE_BUILD_TYPE=Release
      make -j$(nproc)
      ls -l libnativeQt.so # 产物必须落在这里(cjpm.toml 的 ffi 路径指向此目录)

 

posted @ 2026-11-10 14:17  沉默种子  阅读(7)  评论(0)    收藏  举报