MFC转QT:Qt高级特性 - QGraphicsScene/QGraphicsView
ccwgpt 2025-06-30 15:00 13 浏览 0 评论
QGraphicsScene框架概述
QGraphicsScene/QGraphicsView框架是Qt提供的一套强大的图形视图系统,用于处理大量图形项的显示、交互和动画。这是MFC所不具备的功能,对于需要复杂交互图形界面的应用来说是一个巨大的优势。
核心组件
图形视图框架主要由三个核心类组成:
- QGraphicsScene - 管理场景中的所有图形项
- QGraphicsView - 显示场景的视图窗口,提供滚动、缩放等功能
- QGraphicsItem - 场景中的各种图形项的基类
这种场景-视图分离的架构提供了极大的灵活性:
- 一个场景可以被多个视图显示
- 图形项可以独立于视图的坐标系统
- 支持深度排序、分组和嵌套
与MFC的对比
MFC没有直接对应的框架,最接近的可能是:
- 使用自定义CView子类实现绘图
- 自行管理绘图对象的集合
- 手动处理缩放、滚动和选择
Qt的图形视图框架提供了这些功能的完整解决方案,极大减少了开发时间和代码复杂度。
基本使用
创建场景和视图
// 创建场景
QGraphicsScene *scene = new QGraphicsScene(this);
scene->setSceneRect(-200, -200, 400, 400); // 设置场景坐标范围
// 创建视图
QGraphicsView *view = new QGraphicsView(scene, this);
view->setRenderHint(QPainter::Antialiasing); // 启用抗锯齿
view->setDragMode(QGraphicsView::RubberBandDrag); // 启用框选模式
view->setOptimizationFlags(QGraphicsView::DontSavePainterState);
view->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
view->setTransformationAnchor(QGraphicsView::AnchorUnderMouse); // 缩放围绕鼠标
// 将视图添加到布局
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(view);
setLayout(layout);
添加图形项
// 添加矩形
QGraphicsRectItem *rect = scene->addRect(-50, -50, 100, 100);
rect->setPen(QPen(Qt::black, 2));
rect->setBrush(QBrush(Qt::blue));
rect->setFlag(QGraphicsItem::ItemIsMovable);
rect->setFlag(QGraphicsItem::ItemIsSelectable);
// 添加椭圆
QGraphicsEllipseItem *ellipse = scene->addEllipse(50, 50, 100, 60);
ellipse->setPen(QPen(Qt::red, 2));
ellipse->setBrush(QBrush(Qt::green));
ellipse->setFlag(QGraphicsItem::ItemIsMovable);
ellipse->setFlag(QGraphicsItem::ItemIsSelectable);
// 添加文本
QGraphicsTextItem *text = scene->addText("Hello QGraphicsScene");
text->setPos(-100, 80);
text->setFont(QFont("Arial", 12));
text->setFlag(QGraphicsItem::ItemIsMovable);
text->setFlag(QGraphicsItem::ItemIsSelectable);
// 添加简单图像
QPixmap pixmap(":/images/logo.png");
QGraphicsPixmapItem *pixmapItem = scene->addPixmap(pixmap);
pixmapItem->setPos(0, -100);
pixmapItem->setFlag(QGraphicsItem::ItemIsMovable);
视图控制
// 缩放视图
view->scale(1.2, 1.2); // 放大1.2倍
// 旋转视图
view->rotate(45); // 旋转45度
// 滚动视图
view->centerOn(rect); // 中心对准指定项目
// 设置背景
view->setBackgroundBrush(QBrush(Qt::lightGray));
// 自定义变换
QTransform transform;
transform.scale(0.8, 0.8);
transform.rotate(30);
view->setTransform(transform);
自定义图形项
基本图形项
通过继承QGraphicsItem可以创建自定义图形项:
class MyCustomItem : public QGraphicsItem
{
public:
MyCustomItem(QGraphicsItem *parent = nullptr)
: QGraphicsItem(parent)
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemIsSelectable);
setFlag(QGraphicsItem::ItemSendsGeometryChanges);
}
// 定义项目边界
QRectF boundingRect() const override
{
return QRectF(-50, -50, 100, 100);
}
// 提供精确碰撞检测形状(可选)
QPainterPath shape() const override
{
QPainterPath path;
path.addEllipse(boundingRect());
return path;
}
// 绘制项目
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget) override
{
// 绘制选中状态效果
if (option->state & QStyle::State_Selected) {
painter->setPen(QPen(Qt::blue, 2, Qt::DashLine));
painter->drawRect(boundingRect());
}
// 绘制实际内容
painter->setPen(QPen(Qt::black, 1));
painter->setBrush(QBrush(Qt::yellow));
painter->drawEllipse(-30, -30, 60, 60);
// 绘制文本
painter->setFont(QFont("Arial", 10));
painter->drawText(boundingRect(), Qt::AlignCenter, "自定义项");
}
protected:
// 处理项目状态变化
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override
{
if (change == ItemPositionChange) {
// 限制移动范围
QPointF newPos = value.toPointF();
QRectF rect = scene()->sceneRect();
if (!rect.contains(newPos)) {
newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left())));
newPos.setY(qMin(rect.bottom(), qMax(newPos.y(), rect.top())));
return newPos;
}
}
return QGraphicsItem::itemChange(change, value);
}
// 处理鼠标事件
void mousePressEvent(QGraphicsSceneMouseEvent *event) override
{
setCursor(Qt::ClosedHandCursor);
QGraphicsItem::mousePressEvent(event);
}
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override
{
setCursor(Qt::OpenHandCursor);
QGraphicsItem::mouseReleaseEvent(event);
}
};
// 使用自定义项目
MyCustomItem *customItem = new MyCustomItem();
customItem->setPos(0, 0);
scene->addItem(customItem);
复合项目和分组
QGraphicsItemGroup可以将多个项目分组,作为一个整体移动和变换:
// 创建项目组
QGraphicsItemGroup *group = new QGraphicsItemGroup();
scene->addItem(group);
// 创建组内项目
QGraphicsRectItem *groupRect = new QGraphicsRectItem(-40, -40, 80, 80);
groupRect->setBrush(Qt::yellow);
QGraphicsEllipseItem *groupEllipse = new QGraphicsEllipseItem(-30, -30, 60, 60);
groupEllipse->setBrush(Qt::red);
// 将项目添加到组
group->addToGroup(groupRect);
group->addToGroup(groupEllipse);
// 设置组属性
group->setFlag(QGraphicsItem::ItemIsMovable);
group->setFlag(QGraphicsItem::ItemIsSelectable);
group->setPos(100, 100);
父子项关系
QGraphicsItem支持项目间的父子关系,子项会跟随父项移动和变换:
// 创建父项
QGraphicsRectItem *parentItem = new QGraphicsRectItem(-50, -50, 100, 100);
parentItem->setBrush(QBrush(Qt::blue));
parentItem->setFlag(QGraphicsItem::ItemIsMovable);
scene->addItem(parentItem);
// 创建子项
QGraphicsEllipseItem *childItem = new QGraphicsEllipseItem(-20, -20, 40, 40, parentItem);
childItem->setBrush(QBrush(Qt::red));
childItem->setFlag(QGraphicsItem::ItemIsSelectable);
// 子项的坐标是相对于父项的
QGraphicsTextItem *textItem = new QGraphicsTextItem("子项", parentItem);
textItem->setPos(0, 0); // 相对于父项的中心
交互功能
事件处理
QGraphicsItem可以处理多种鼠标、键盘等交互事件:
class InteractiveItem : public QGraphicsRectItem
{
public:
InteractiveItem(QGraphicsItem *parent = nullptr)
: QGraphicsRectItem(-50, -30, 100, 60, parent)
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemIsSelectable);
setFlag(QGraphicsItem::ItemIsFocusable);
setBrush(QBrush(Qt::lightGray));
setPen(QPen(Qt::black, 2));
}
protected:
// 鼠标按下
void mousePressEvent(QGraphicsSceneMouseEvent *event) override
{
setBrush(QBrush(Qt::yellow));
QGraphicsRectItem::mousePressEvent(event);
}
// 鼠标释放
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override
{
setBrush(QBrush(Qt::lightGray));
QGraphicsRectItem::mouseReleaseEvent(event);
}
// 鼠标双击
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override
{
// 改变大小
setRect(rect().adjusted(-10, -10, 10, 10));
QGraphicsRectItem::mouseDoubleClickEvent(event);
}
// 鼠标悬停
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override
{
setPen(QPen(Qt::red, 3));
}
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override
{
setPen(QPen(Qt::black, 2));
}
// 键盘事件
void keyPressEvent(QKeyEvent *event) override
{
switch (event->key()) {
case Qt::Key_Plus:
// 放大
setScale(scale() * 1.1);
break;
case Qt::Key_Minus:
// 缩小
setScale(scale() / 1.1);
break;
case Qt::Key_Space:
// 旋转
setRotation(rotation() + 15);
break;
default:
QGraphicsRectItem::keyPressEvent(event);
}
}
};
// 使用交互项
InteractiveItem *interactiveItem = new InteractiveItem();
interactiveItem->setPos(0, 0);
scene->addItem(interactiveItem);
// 激活悬停事件
interactiveItem->setAcceptHoverEvents(true);
拖放支持
QGraphicsItem可以支持拖放操作:
class DraggableItem : public QGraphicsRectItem
{
public:
DraggableItem() : QGraphicsRectItem(-50, -30, 100, 60)
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemIsSelectable);
setBrush(QBrush(Qt::green));
setAcceptDrops(true);
}
protected:
void dragEnterEvent(QGraphicsSceneDragDropEvent *event) override
{
if (event->mimeData()->hasText()) {
event->accept();
setBrush(QBrush(Qt::yellow));
} else {
event->ignore();
}
}
void dragLeaveEvent(QGraphicsSceneDragDropEvent *event) override
{
setBrush(QBrush(Qt::green));
QGraphicsRectItem::dragLeaveEvent(event);
}
void dropEvent(QGraphicsSceneDragDropEvent *event) override
{
if (event->mimeData()->hasText()) {
QString text = event->mimeData()->text();
// 处理拖放的文本
QGraphicsTextItem *textItem = new QGraphicsTextItem(this);
textItem->setPlainText(text);
textItem->setPos(-textItem->boundingRect().width()/2, 0);
setBrush(QBrush(Qt::green));
event->accept();
}
}
};
高级功能
缓存与性能优化
对于复杂或大量的图形项,可以使用项目缓存提高性能:
// 启用项目缓存
myComplexItem->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
// 不同缓存模式
// ItemCoordinateCache - 适合不经常变换但内容复杂的项目
// DeviceCoordinateCache - 适合经常移动但不旋转/缩放的项目
// NoCache - 适合频繁改变外观的项目
自定义视图与场景交互
通过子类化QGraphicsView可以自定义视图交互行为:
class CustomView : public QGraphicsView
{
public:
CustomView(QGraphicsScene *scene) : QGraphicsView(scene)
{
// 设置视图属性
setRenderHint(QPainter::Antialiasing);
setDragMode(QGraphicsView::RubberBandDrag);
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
}
protected:
// 鼠标滚轮事件 - 实现缩放
void wheelEvent(QWheelEvent *event) override
{
// 缩放因子
double scaleFactor = 1.15;
if (event->angleDelta().y() > 0) {
// 放大
scale(scaleFactor, scaleFactor);
} else {
// 缩小
scale(1.0 / scaleFactor, 1.0 / scaleFactor);
}
}
// 键盘事件 - 实现平移
void keyPressEvent(QKeyEvent *event) override
{
switch (event->key()) {
case Qt::Key_Up:
translate(0, 10);
break;
case Qt::Key_Down:
translate(0, -10);
break;
case Qt::Key_Left:
translate(10, 0);
break;
case Qt::Key_Right:
translate(-10, 0);
break;
case Qt::Key_Home:
// 重置变换
resetTransform();
break;
default:
QGraphicsView::keyPressEvent(event);
}
}
// 鼠标按下事件 - 实现拖动
void mousePressEvent(QMouseEvent *event) override
{
if (event->button() == Qt::MiddleButton) {
// 中键拖动
setDragMode(QGraphicsView::ScrollHandDrag);
setInteractive(false);
QMouseEvent fakeEvent(QEvent::MouseButtonPress,
event->pos(), Qt::LeftButton,
Qt::LeftButton, Qt::NoModifier);
QGraphicsView::mousePressEvent(&fakeEvent);
event->accept();
return;
}
QGraphicsView::mousePressEvent(event);
}
void mouseReleaseEvent(QMouseEvent *event) override
{
if (event->button() == Qt::MiddleButton) {
// 恢复默认模式
setDragMode(QGraphicsView::RubberBandDrag);
setInteractive(true);
QMouseEvent fakeEvent(QEvent::MouseButtonRelease,
event->pos(), Qt::LeftButton,
Qt::LeftButton, Qt::NoModifier);
QGraphicsView::mouseReleaseEvent(&fakeEvent);
event->accept();
return;
}
QGraphicsView::mouseReleaseEvent(event);
}
};
导出和打印
场景可以导出为图像或直接打印:
// 导出场景为图像
void exportScene(QGraphicsScene *scene, const QString &fileName,
const QSize &imageSize = QSize(800, 600))
{
QImage image(imageSize, QImage::Format_ARGB32_Premultiplied);
image.fill(Qt::white);
QPainter painter(&image);
painter.setRenderHint(QPainter::Antialiasing);
scene->render(&painter);
painter.end();
image.save(fileName);
}
// 打印场景
void printScene(QGraphicsScene *scene)
{
QPrinter printer(QPrinter::HighResolution);
QPrintDialog dialog(&printer);
if (dialog.exec() == QDialog::Accepted) {
QPainter painter(&printer);
painter.setRenderHint(QPainter::Antialiasing);
scene->render(&painter);
painter.end();
}
}
实际应用示例
简单流程图编辑器
以下是一个流程图编辑器的简化示例:
// 流程图节点
class FlowChartNode : public QGraphicsRectItem
{
public:
FlowChartNode(const QString &text)
: QGraphicsRectItem(-75, -30, 150, 60)
{
setBrush(QBrush(Qt::white));
setPen(QPen(Qt::black, 2));
setFlags(QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsSelectable |
QGraphicsItem::ItemSendsGeometryChanges);
// 添加文本
textItem = new QGraphicsTextItem(this);
textItem->setPlainText(text);
textItem->setPos(-textItem->boundingRect().width()/2,
-textItem->boundingRect().height()/2);
// 创建连接点
createConnectionPoints();
}
QPointF connectionPoint(int index) const
{
if (index >= 0 && index < connectionPoints.size())
return connectionPoints[index]->scenePos();
return QPointF();
}
void setText(const QString &text)
{
textItem->setPlainText(text);
textItem->setPos(-textItem->boundingRect().width()/2,
-textItem->boundingRect().height()/2);
}
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override
{
if (change == ItemPositionHasChanged) {
// 通知连接线更新
foreach (QGraphicsItem *item, scene()->items()) {
FlowChartConnection *connection =
dynamic_cast<FlowChartConnection*>(item);
if (connection &&
(connection->sourceNode() == this ||
connection->destNode() == this)) {
connection->updatePosition();
}
}
}
return QGraphicsRectItem::itemChange(change, value);
}
private:
void createConnectionPoints()
{
// 上、右、下、左四个连接点
connectionPoints.append(createConnectionPoint(0, -30)); // 上
connectionPoints.append(createConnectionPoint(75, 0)); // 右
connectionPoints.append(createConnectionPoint(0, 30)); // 下
connectionPoints.append(createConnectionPoint(-75, 0)); // 左
}
QGraphicsRectItem *createConnectionPoint(qreal x, qreal y)
{
QGraphicsRectItem *point = new QGraphicsRectItem(-4, -4, 8, 8, this);
point->setBrush(QBrush(Qt::black));
point->setPen(Qt::NoPen);
point->setPos(x, y);
return point;
}
QList<QGraphicsRectItem*> connectionPoints;
QGraphicsTextItem *textItem;
};
// 流程图连接线
class FlowChartConnection : public QGraphicsPathItem
{
public:
FlowChartConnection(FlowChartNode *sourceNode, int sourcePointIndex,
FlowChartNode *destNode, int destPointIndex)
: sourceNode_(sourceNode), destNode_(destNode),
sourcePointIndex_(sourcePointIndex), destPointIndex_(destPointIndex)
{
setPen(QPen(Qt::black, 2));
setFlag(QGraphicsItem::ItemIsSelectable);
updatePosition();
}
void updatePosition()
{
if (!sourceNode_ || !destNode_)
return;
QPointF sourcePoint = sourceNode_->connectionPoint(sourcePointIndex_);
QPointF destPoint = destNode_->connectionPoint(destPointIndex_);
QPainterPath path;
path.moveTo(sourcePoint);
// 创建贝塞尔曲线连接
QPointF control1, control2;
calculateControlPoints(sourcePoint, destPoint, control1, control2);
path.cubicTo(control1, control2, destPoint);
setPath(path);
}
FlowChartNode *sourceNode() const { return sourceNode_; }
FlowChartNode *destNode() const { return destNode_; }
private:
void calculateControlPoints(const QPointF &source, const QPointF &dest,
QPointF &control1, QPointF &control2)
{
// 简单控制点计算
qreal dx = dest.x() - source.x();
qreal dy = dest.y() - source.y();
control1 = QPointF(source.x() + dx * 0.4, source.y());
control2 = QPointF(dest.x() - dx * 0.4, dest.y());
}
FlowChartNode *sourceNode_;
FlowChartNode *destNode_;
int sourcePointIndex_;
int destPointIndex_;
};
// 使用示例
void setupFlowChart(QGraphicsScene *scene)
{
// 创建节点
FlowChartNode *startNode = new FlowChartNode("开始");
startNode->setPos(0, -150);
scene->addItem(startNode);
FlowChartNode *processNode = new FlowChartNode("处理");
processNode->setPos(0, 0);
scene->addItem(processNode);
FlowChartNode *decisionNode = new FlowChartNode("判断");
decisionNode->setPos(0, 150);
scene->addItem(decisionNode);
FlowChartNode *endNode = new FlowChartNode("结束");
endNode->setPos(150, 300);
scene->addItem(endNode);
// 创建连接
FlowChartConnection *conn1 =
new FlowChartConnection(startNode, 2, processNode, 0);
scene->addItem(conn1);
FlowChartConnection *conn2 =
new FlowChartConnection(processNode, 2, decisionNode, 0);
scene->addItem(conn2);
FlowChartConnection *conn3 =
new FlowChartConnection(decisionNode, 2, endNode, 0);
scene->addItem(conn3);
}
从MFC迁移的建议
1. 功能映射
MFC实现 | Qt Graphics框架 |
自定义CView | QGraphicsView |
手动管理对象集合 | QGraphicsScene |
自定义CObject子类 | QGraphicsItem子类 |
滚动管理 | 自动处理 |
缩放实现 | 简单的view->scale() |
自定义绘制 | 项目的paint()方法 |
选择处理 | 内置的选择功能 |
拖放支持 | 内置的拖放功能 |
2. 迁移策略
- 先构建骨架: 创建基本的场景和视图框架
- 分批转换绘图代码: 将MFC应用中的绘图对象逐个转换为QGraphicsItem子类
- 重构交互逻辑: 基于项目的事件系统重构交互代码
- 利用内置功能: 使用Qt内置的选择、拖放、变换功能简化代码
- 提高性能: 利用缓存模式和其他优化
3. 常见挑战
- 坐标系差异: MFC通常使用基于窗口的坐标,而Qt Graphics使用场景坐标
- 交互模型不同: 基于消息的MFC交互与基于对象的Qt交互有较大差别
- 选择管理: MFC通常需要手动管理选择,而Qt有内置功能
- 性能考虑: 大型场景需要考虑缓存和其他性能优化技术
相关推荐
- 一个基于.Net Core遵循Clean Architecture原则开源架构
-
今天给大家推荐一个遵循CleanArchitecture原则开源架构。项目简介这是基于Asp.netCore6开发的,遵循CleanArchitecture原则,可以高效、快速地构建基于Ra...
- AI写代码翻车无数次,我发现只要提前做好这3步,bug立减80%
-
写十万行全是bug之后终于找到方法了开发"提示词管理助手"新版本那会儿,我差点被bug整崩溃。刚开始两周,全靠AI改代码架构,结果十万行程序漏洞百出。本来以为AI说没问题就稳了,结果...
- OneCode低代码平台的事件驱动设计:架构解析与实践
-
引言:低代码平台的事件驱动范式在现代软件开发中,事件驱动架构(EDA)已成为构建灵活、松耦合系统的核心范式。OneCode低代码平台通过创新性的注解驱动设计,将事件驱动理念深度融入平台架构,实现了业务...
- 国内大厂AI插件评测:根据UI图生成Vue前端代码
-
在IDEA中安装大厂的AI插件,打开ruoyi增强项目:yudao-ui-admin-vue31.CodeBuddy插件登录腾讯的CodeBuddy后,大模型选择deepseek-v3,输入提示语:...
- AI+低代码技术揭秘(二):核心架构
-
本文档介绍了为VTJ低代码平台提供支持的基本架构组件,包括Engine编排层、Provider服务系统、数据模型和代码生成管道。有关UI组件库和widget系统的信息,请参阅UI...
- GitDiagram用AI把代码库变成可视化架构图
-
这是一个名为gitdiagram的开源工具,可将GitHub仓库实时转换为交互式架构图,帮助开发者快速理解代码结构。核心功能一键可视化:替换GitHubURL中的"hub...
- 30天自制操作系统:第六天:代码架构整理与中断处理
-
1.拆开bootpack.c文件。根据设计模式将对应的功能封装成独立的文件。2.初始化pic:pic(可编程中断控制器):在设计上,cpu单独只能处理一个中断。而pic是将8个中断信号集合成一个中断...
- AI写代码越帮越忙?2025年研究揭露惊人真相
-
近年来,AI工具如雨后春笋般涌现,许多人开始幻想程序员的未来就是“对着AI说几句话”,就能轻松写出完美的代码。然而,2025年的一项最新研究却颠覆了这一期待,揭示了一个令人意外的结果。研究邀请了16位...
- 一键理解开源项目:两个自动生成GitHub代码架构图与说明书工具
-
一、GitDiagram可以一键生成github代码仓库的架构图如果想要可视化github开源项目:https://github.com/luler/reflex_ai_fast,也可以直接把域名替换...
- 5分钟掌握 c# 网络通讯架构及代码示例
-
以下是C#网络通讯架构的核心要点及代码示例,按协议类型分类整理:一、TCP协议(可靠连接)1.同步通信//服务器端usingSystem.Net.Sockets;usingTcpListene...
- 从复杂到优雅:用建造者和责任链重塑代码架构
-
引用设计模式是软件开发中的重要工具,它为解决常见问题提供了标准化的解决方案,提高了代码的可维护性和可扩展性,提升了开发效率,促进了团队协作,提高了软件质量,并帮助开发者更好地适应需求变化。通过学习和应...
- 低代码开发当道,我还需要学习LangChain这些框架吗?| IT杂谈
-
专注LLM深度应用,关注我不迷路前两天有位兄弟问了个问题:当然我很能理解这位朋友的担忧:期望效率最大化,时间用在刀刃上,“不要重新发明轮子”嘛。铺天盖地的AI信息轰炸与概念炒作,很容易让人浮躁与迷茫。...
- 框架设计并不是简单粗暴地写代码,而是要先弄清逻辑
-
3.框架设计3.框架设计本节我们要开发一个UI框架,底层以白鹭引擎为例。框架设计的第一步并不是直接撸代码,而是先想清楚设计思想,抽象。一个一个的UI窗口是独立的吗?不是的,...
- 大佬用 Avalonia 框架开发的 C# 代码 IDE
-
AvalonStudioAvalonStudio是一个开源的跨平台的开发编辑器(IDE),AvalonStudio的目标是成为一个功能齐全,并且可以让开发者快速使用的IDE,提高开发的生产力。A...
- 轻量级框架Lagent 仅需20行代码即可构建自己的智能代理
-
站长之家(ChinaZ.com)8月30日消息:Lagent是一个专注于基于LLM模型的代理开发的轻量级框架。它的设计旨在简化和提高这种模型下代理的开发效率。LLM模型是一种强大的工具,可以...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- mfc框架 (52)
- abb框架断路器 (48)
- beego框架 (52)
- java框架spring (58)
- grpc框架 (65)
- tornado框架 (48)
- 前端框架bootstrap (54)
- orm框架有哪些 (51)
- 知识框架图 (52)
- ppt框架 (55)
- 框架图模板 (59)
- 内联框架 (52)
- cad怎么画框架 (58)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)