【Qt】系统相关(1)——事件
Qt系统相关1. Qt事件2. 处理事件2.1 enterEvent leaveEvent2.2鼠标事件3. 键盘按键事件4. 定时事件4.1设置定时4.2 获取系统日期及时间5.事件分发器5.1派发器的原理6. 移动窗口和改变大小事件1. Qt事件信号槽与事件之间的关系信号槽我们之前对信号槽的定义是用户进行各种操作就有可能能产生信号我们可以给这个信号关联一个参函数当触发这个信号的时候执行对应的槽函数。事件其实和信号槽机制很像也是用户进行各种操作同样也可能产生事件。同样可以给对应的事件关联处理函数处理逻辑当事件触发的时候就能够处理对应的处理函数。事件本身是操作系统提供的机制Qt也同样把操作系统事件进行了封装拿到了Qt中。但是对应事件的代码边写起来不方便。于是Qt对于事件又进行了封装就得到了信号槽。所以对于信号槽来说事件就是它的底层机制。而实际上Qt开发过程中绝大部分和用户的交互都是通过信号槽机制进行的。但是有些特殊情况下信号槽不一定能完成比如某些用户的动作没有对应的Qt信号那么此时就需要通过重写事件处理函数来手动处理用户的响应。在Qt平台中使用一个对象来表示一个事件。所有的Qt事件均继承于抽象类QEvent。事件是由系统或者Qt平台本身在不同的时刻发出的。当用户按下鼠标、敲下键盘或者是窗口需要重新绘制的时候都会发出⼀个相应的事件。⼀些事件是在用户操作时发出如键盘事件、鼠标事件等另⼀些事件则是由系统本身自动发出如定时器事件。常见的Qt事件如下事件名称描述鼠标事件鼠标左键、鼠标右键、鼠标滚轮鼠标的移动鼠标按键的按下和松开键盘事件按键类型、按键按下、按键松开定时器事件定时时间到达进入离开事件鼠标的进入和离开滚轮事件鼠标滚轮滚动绘屏事件重绘屏幕的某些部分显示隐藏事件窗口的显示和隐藏移动事件窗口位置的变化窗口事件是否为当前窗口大小改变事件窗口大小改变焦点事件键盘焦点移动拖拽事件用鼠标进行拖拽2. 处理事件之前的信号槽机制是通过connect函数进行关联度的但是Qt事件的处理方式就有点不一样了。Qt的事件是通过重写某个事件处理函数来进行的。在Qt中几乎所有的Event事件都是虚函数所有可以进行重写实现。这里用到的是多态机制。步骤一般是首先创建子类继承自Qt中已有的事件类然后在子类中重写处理函数。这样后续事件触发的时候就会通过多态机制执行我们重写的事件处理函数了。2.1 enterEvent leaveEvent示例实现鼠标进入事件enterEvent和离开事件leaveEvent[virtual protected]voidQWidget::enterEvent(QEvent*event)This event handler can be reimplemented in a subclass to receive widget enter events which are passed in the event parameter.An event is sent to the widget when the mouse cursor enters the widget.See alsoleaveEvent(),mouseMoveEvent(),andevent().[virtual protected]voidQWidget::leaveEvent(QEvent*event)This event handler can be reimplemented in a subclass to receive widget leave events which are passed in the event parameter.A leave event is sent to the widget when the mouse cursor leaves the widget.See alsoenterEvent(),mouseMoveEvent(),andevent().首先创建一个Label类继承自QLabel此时就需要在生成的子类中重写上面两个函数注意一定要保证函数名和参数类型保持一致Label.h#includeQLabelclass Label:public QLabel{Q_OBJECT public:Label(QWidget*parent);voidenterEvent(QEvent*envet);voidleaveEvent(QEvent*envet);};Label.cpp#includeQDebugLabel::Label(QWidget*parent):QLabel(parent){}voidLabel::enterEvent(QEvent*envet){(void)envet;qDebug()enterEvent;}voidLabel::leaveEvent(QEvent*envet){(void)envet;qDebug()leaveEvent;}但是这个时候还不能进行触发。现在可以通过两种方式进行触发第一种就是使用我们自己创建的Label类生成第二种就是使用ui界面的升级控件来进行。第一种Widget::Widget(QWidget*parent):QWidget(parent),ui(new Ui::Widget){ui-setupUi(this);Label*labelnewLabel(this);label-setText(这是一个代码生成的标签);}第二种方法右击控件选择提升为此时就可以触发事件了。示例实现一个鼠标移动到按钮上时按钮移动同样的首先要创建一个PushButton继承自QPushBUttonpushButton.h#includeQWidget#includeQPushButtonclass PushButton:public QPushButton{Q_OBJECT public:PushButton(QWidget*parent);voidenterEvent(QEvent*event);// 重写鼠标进入事件public:QRect rect;// 创建一个QRect类来存放父窗口的窗口信息};pushButton.cpp#includeQDebug#includerandomPushButton::PushButton(QWidget*parent):QPushButton(parent){rectparent-geometry();// 获取父窗口的窗口信息srand((unsigned)0);// 设置随机种子}voidPushButton::enterEvent(QEvent*event){QRect rthis-geometry();// 获取按钮的信息qDebug()rrect;intxrand()%(rect.width()-r.width());intyrand()%(rect.height()-r.height());this-setGeometry(x,y,r.width(),r.height());// 重写设置按钮的信息}widget.cpp#includepushbutton.hWidget::Widget(QWidget*parent):QWidget(parent),ui(new Ui::Widget){ui-setupUi(this);PushButton*buttonnewPushButton(this);button-setText(按钮);}2.2鼠标事件函数介绍鼠标按下事件[override virtual protected]voidQLabel::mousePressEvent(QMouseEvent*ev)Reimplements:QWidget::mousePressEvent(QMouseEvent*event).同时这里说明一下这个鼠标按下指的是只要鼠标上的按钮按下就会触发无论是鼠标左键右键侧键中键只要是鼠标上的按钮就可以触发。voidLabel::mousePressEvent(QMouseEvent*ev){if(ev-button()Qt::LeftButton){qDebug()鼠标左键被按下;}elseif(ev-button()Qt::RightButton){qDebug()鼠标右键被按下;}// 这个是以屏幕的左上角为原点qDebug()ev-globalX()ev-globalY();// 这个是以标签的左上角为原点qDebug()ev-x(), ev-y();}同理我们还有鼠标释放事件[override virtual protected]voidQLabel::mouseReleaseEvent(QMouseEvent*ev)Reimplements:QWidget::mouseReleaseEvent(QMouseEvent*event).鼠标双击事件[virtual protected]voidQWidget::mouseDoubleClickEvent(QMouseEvent*event)This event handler,forevent event,can be reimplemented in a subclass to receive mousedoubleclick eventsforthe widget.鼠标移动事件[virtual protected]voidQWidget::mouseMoveEvent(QMouseEvent*event)This event handler,forevent event,can be reimplemented in a subclass to receive mouse move eventsforthe widget.If mouse tracking is switched off,mouse move events only occurifa mouse button is pressedwhilethe mouse is being moved.If mouse tracking is switched on,mouse move events occur evenifno mouse button is pressed.QMouseEvent::pos()reports the position of the mouse cursor,relative to this widget.For press and release events,the position is usually the same as the position of the last mouse move event,but it might be differentifthe users hand shakes.This is a feature of the underlying window system,not Qt.If you want to show a tooltip immediately,whilethe mouse ismoving(e.g.,to get the mouse coordinates with QMouseEvent::pos()and show them as a tooltip),you must first enable mouse tracking as described above.Then,to ensure that the tooltip is updated immediately,you must call QToolTip::showText()instead ofsetToolTip()in your implementation ofmouseMoveEvent().前面的代码我们都是在自定义的Label中完成的并且鼠标的作用范围也只是在Label范围内生效。但是如果我们想在窗口中执行也适可以的我们只需要直接在WidgetQWidget的子类进行扩展就行了。也就是直接在WIdget中重写事件函数即可。但是这个鼠标移动事件和上面的鼠标点击时间有所不同由于我们鼠标只需要随便移动一下就可以触发移动事件也就会产生大量的事件一旦我们要处理一些复杂的任务的时候就很容易让程序的负担加重就很容易卡顿。所以Qt为了程序的流畅性默认情况下是不会对鼠标进行追踪的也就是鼠标移动的时候不会调用mouseMoveEvent函数。而要让程序追踪鼠标就必须主动告诉程序就需要调用setMouseTracking函数。Widget::Widget(QWidget*parent):QWidget(parent),ui(new Ui::Widget){ui-setupUi(this);// 把这个选项设置为true才能够追踪到鼠标的移动位置this-setMouseTracking(true);}Widget::~Widget(){delete ui;}voidWidget::mouseMoveEvent(QMouseEvent*event){qDebug()event-x(), event-y();}鼠标滚轮事件[virtual protected]voidQWidget::wheelEvent(QWheelEvent*event)This event handler,forevent event,can be reimplemented in a subclass to receive wheel eventsforthe widget.If you reimplement this handler,it is very important that youignore()the eventifyoudonot handle it,so that the widgets parent can interpret it.Thedefaultimplementation ignores the event.可以通过delta函数获取滚动的数值。voidWidget::wheelEvent(QWheelEvent*event){totalevent-delta();qDebug()total;}3. 键盘按键事件[virtual protected]voidQWidget::keyPressEvent(QKeyEvent*event)This event handler,forevent event,can be reimplemented in a subclass to receive key press eventsforthe widget.A widget must callsetFocusPolicy()to accept focus initially and have focus in order to receive a key press event.If you reimplement this handler,it is very important that you call the base class implementationifyoudonot act upon the key.Thedefaultimplementation closes popup widgetsifthe user presses the key sequenceforQKeySequence::Cancel(typically the Escape key).Otherwise the event is ignored,so that the widgets parent can interpret it.Note that QKeyEvent starts withisAccepted()true,so youdonot need to call QKeyEvent::accept()-justdonot call the base class implementationifyou act upon the key.voidWidget::keyPressEvent(QKeyEvent*event){qDebug()event-key();// 当我们需要按下组合键时需要用到modifiers函数if(event-key()Qt::Key_Aevent-modifiers()Qt::ControlModifier)qDebug()按下了Ctrl A;}4. 定时事件4.1设置定时Qt中在进行窗口程序的处理过程中经常要周期性的执行某些操作或者制作⼀些动画效果使用定时器就可以实现。所谓定时器就是在间隔⼀定时间后去执行某⼀个任务。定时器在很多场景下都会使用到如弹窗自动关闭之类的功能等。Qt中的定时器分为QTimerEvent和QTimer这2个类。QTimerEvent类用来描述⼀个定时器事件。在使用时需要通过startTimer()函数来开启⼀个定时器这个函数需要输入一个以毫秒为单位的整数作为参数来表明设定的时间它返回的整型值代表这个定时器而且这个定时器唯一标识这个定时器。当定时器溢出时即定时时间到达就会触发timerEvent()函数使用killTimer()关闭一个定时器从而获取该定时器的编号来进行相关操作。QTimer类来实现⼀个定时器它提供了更高层次的编程接口如可以使用信号和槽还可以设置只运行一次的定时器。而QTimer其实就是QTimerEvent封装后的结果。方法一使用QTimerEventtimerEvent函数介绍[virtual protected]voidQObject::timerEvent(QTimerEvent*event)This event handler can be reimplemented in a subclass to receive timer eventsforthe object.QTimer provides a higher-level interface to the timer functionality,and also more general information about timers.The timer event is passed in the event parameter.Widget::Widget(QWidget*parent):QWidget(parent),ui(new Ui::Widget){ui-setupUi(this);// 此处开启定时器timerIdthis-startTimer(1000);}Widget::~Widget(){delete ui;}voidWidget::timerEvent(QTimerEvent*event){// 一个程序种可能存在多个定时器所以需要使用timerId来确定是那个定时器触发的if(event-timerId()!timerId){return;}intvalueui-lcdNumber-intValue();if(value0){// 停止定时器this-killTimer(this-timerId);return;}value-1;ui-lcdNumber-display(value);}方法二使用QTimer#includeQTimer#includeQPushButtonWidget::Widget(QWidget*parent):QWidget(parent),ui(new Ui::Widget){ui-setupUi(this);// 此处开启定时器timerIdthis-startTimer(1000);QTimer*timenewQTimer(this);connect(ui-pushButton,QPushButton::clicked,this,[](){time-start(1000);});connect(time,QTimer::timeout,this,[](){staticintnum1;ui-label-setText(QString::number(num));});connect(ui-pushButton_2,QPushButton::clicked,this,[](){time-stop();});}4.2 获取系统日期及时间在Qt中获取系统日期和时间可以通过QTimer和QDataTime类获取QDateTime类提供了字符串格式的时间。字符串形式的时间输出格式由toString()方法中的format参数列表决定可用的参数列表如下现在我们实现一个例子展示的效果就是我们结合一个定时器每过一秒中就显示当前时间同时各两个按钮一个开始一个停止按钮。#includeQDateTime#includeQTimerWidget::Widget(QWidget*parent):QWidget(parent),ui(new Ui::Widget){ui-setupUi(this);QTimer*timenewQTimer(this);connect(ui-pushButton,QPushButton::clicked,this,[](){time-start(1000);});connect(ui-pushButton_2,QPushButton::clicked,this,[](){time-stop();});connect(time,QTimer::timeout,this,Widget::handel);}Widget::~Widget(){delete ui;}voidWidget::handel(){QString strQDateTime::currentDateTime().toString(yyyy-MM-dd hh:mm:ss);ui-label-setText(str);}5.事件分发器在Qt中事件分发器(EventDispatcher)是⼀个核⼼概念⽤处理GUI应用程序中的事件。事件分发器负责将事件从⼀个对象传递到另⼀个对象直到事件被处理或被取消。每个继承自QObject类或QObject类本身都可以在本类中重写boolevent(QEvent*e)函数来实现相关事件的捕获和拦截。5.1派发器的原理在Qt中我们发送的事件都是传给了QObject对象更具体点是传给了QObject对象的event()函数。所有的事件都会进入到这个函数里面那么我们处理事件就要重写这个event()函数。event()函数本身不去处理事件而是根据事件类型type值调用不同的事件处理函数。事件分发器就是工作在应用程序向下分发事件的过程中如下图如上图事件分发器用于分发事件。在此过程中事件分发器也可以做拦截操作。事件分发器主要是通过bool event(QEvent *e)函数来实现。其返回值为布尔类型若为ture代表拦截不向下分发。Qt中的事件是封装QEvent类中在Qt助手中输入QEvent可以查看其所包括的事件类型如下图所示现在我们实现一个拦截器拦截鼠标点击事件voidWidget::mousePressEvent(QMouseEvent*event){if(event-button()Qt::LeftButton){qDebug()鼠标左键被按下;}}bool Widget::event(QEvent*event){if(event-type()QEvent::MouseButtonPress){qDebug()event鼠标左键被按下;returntrue;// 返回true代表不向下分发}// 剩下的交给父类处理默认处理returnQWidget::event(event);}于是当我们点击鼠标左键的时候就不会执行mousePressEvent了但是上面的代码还是会出现一点问题就是当我们连续点击鼠标左键的时候他还是会执行mousePressEvent。这是当你快速点击鼠标左键时Qt 会检测到这是一个双击操作此时第二个点击产生的事件类型不再是QEvent::MouseButtonPress而是 QEvent::MouseButtonDblClick。由于 event() 没有拦截 MouseButtonDblClick这个事件会走到 return QWidget::event(event); 这一行。然后 Qt 父类的QWidget::event() 分发这个双击事件 → 调用 mouseDoubleClickEvent()。而 mouseDoubleClickEvent() 的默认实现恰恰就是调用mousePressEvent()6. 移动窗口和改变大小事件moveEvent[virtual protected]voidQWidget::moveEvent(QMoveEvent*event)This event handler can be reimplemented in a subclass to receive widget move events which are passed in the event parameter.When the widget receives this event,it is already at the new position.resizeEvent[virtual protected]voidQWidget::resizeEvent(QResizeEvent*event)This event handler can be reimplemented in a subclass to receive widget resize events which are passed in the event parameter.WhenresizeEvent()is called,the widget already has its new geometry.The old size is accessible through QResizeEvent::oldSize().The widget will be erased and receive a paint event immediately after processing the resize event.No drawing needbe(or should be)done inside this handler.执行效果展示voidWidget::moveEvent(QMoveEvent*event){qDebug()event-pos();}voidWidget::resizeEvent(QResizeEvent*event){qDebug()event-size();}

相关新闻

Databricks七大核心概念:Workspace、Cluster、Unity Catalog等深度解析

Databricks七大核心概念:Workspace、Cluster、Unity Catalog等深度解析

1. 这不是又一篇“点开就关”的Databricks入门文——它直击数据工程师、分析师和ML工程师每天真实卡壳的7个节点你打开Databricks,新建一个Notebook,敲下spark.read.csv(),数据顺利加载——然后呢?你发现集群启动慢得像在等咖啡机…

2026/7/5 5:31:42阅读更多 →
终极指南:如何用Video2X免费将模糊视频变成4K高清

终极指南:如何用Video2X免费将模糊视频变成4K高清

终极指南:如何用Video2X免费将模糊视频变成4K高清 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/vi/video2x …

2026/7/5 5:31:42阅读更多 →
文献阅读 260704-Global mangrove growth variability driven by climatic oscillation-induced sea-level fluc

文献阅读 260704-Global mangrove growth variability driven by climatic oscillation-induced sea-level fluc

Global mangrove growth variability driven by climatic oscillation-induced sea-level fluctuations 来自 <Global mangrove growth variability driven by climatic oscillation-induced sea-level fluctuations | Nature Geoscience> &#x1f4d1; 读书笔记与文献总…

2026/7/5 5:31:42阅读更多 →
系统动力学驱动的钢铁行业碳排放预测:从模型构建到情景仿真全流程复现

系统动力学驱动的钢铁行业碳排放预测:从模型构建到情景仿真全流程复现

一、钢铁行业的"双碳"困局&#xff0c;为什么需要系统动力学 2021 年&#xff0c;中国粗钢产量突破 10 亿吨&#xff0c;占全球总产量的半壁江山。与这一产能规模并行的是巨大的碳排放压力——钢铁行业贡献了全国碳排放总量的约 15%&#xff0c;在所有工业门类中位居…

2026/7/5 6:36:45阅读更多 →
Riffusion API对接与成本优化实战指南

Riffusion API对接与成本优化实战指南

1. Riffusion API 对接价值解析Riffusion 作为当前最热门的AI音乐生成平台之一&#xff0c;其官方API定价策略存在明显的优化空间。通过技术手段对接Riffusion API&#xff0c;我们能够实现比官方渠道低30%-50%的使用成本&#xff0c;这对需要批量生成音乐内容的创作者和开发者…

2026/7/5 6:36:45阅读更多 →
生信分析实战:巧用循环与向后选择法构建COX预后模型

生信分析实战:巧用循环与向后选择法构建COX预后模型

1. 为什么需要自动化COX预后模型构建在肿瘤基因组学研究中&#xff0c;我们经常需要分析大量基因与患者预后的关联。传统手动操作存在三个明显痛点&#xff1a;首先&#xff0c;当面对数百个候选基因时&#xff0c;逐个进行单变量COX分析会消耗大量时间&#xff1b;其次&#x…

2026/7/5 6:36:45阅读更多 →
音视频参数实战:3步计算1080P 30fps视频的CBR/VBR码率与文件大小

音视频参数实战:3步计算1080P 30fps视频的CBR/VBR码率与文件大小

音视频参数实战&#xff1a;3步计算1080P 30fps视频的CBR/VBR码率与文件大小在流媒体开发与视频处理领域&#xff0c;精确控制码率与文件大小是平衡画质与传输效率的核心技能。本文将带您通过三个可落地的计算步骤&#xff0c;掌握1080P分辨率、30帧率视频的码率配置技巧&#…

2026/7/5 6:36:45阅读更多 →
LinkSwift:九大网盘直链下载的完整解决方案

LinkSwift:九大网盘直链下载的完整解决方案

LinkSwift&#xff1a;九大网盘直链下载的完整解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 / 迅雷…

2026/7/5 6:36:45阅读更多 →
苏州哪里可以买仿真绿植?家用商用采购避坑全解析

苏州哪里可以买仿真绿植?家用商用采购避坑全解析

苏州哪里可以买仿真绿植&#xff1f; 空间软装优化中&#xff0c;绿植是提升环境质感、优化空间氛围的基础物料&#xff0c;广泛应用于家装软装、办公环境布置、线下商业门店装修场景。苏州属于亚热带湿润季风气候&#xff0c;梅雨季湿度偏高&#xff0c;活体绿植养护门槛高、存…

2026/7/5 6:31:45阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述&#xff1a;从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目&#xff0c;叫 skills4/skills &#xff0c;它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景&#xff1a;一个旨在展示或教授某种技能的仓库&#xff0c;本身却成了安…

2026/7/5 0:01:08阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示&#xff1a;因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战&#xff1a;从“黑箱预测”到“可信推理”2026年6月&#xff0c;第7届机器学习与趋势国际会议&#xff08;MLT 2026&#xff09;将在悉尼召开。会议议程中&#xff0c;“因果与可解释机器学习…

2026/7/5 0:01:08阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时&#xff0c;通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中&#xff0c;是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/5 0:01:08阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述&#xff1a;从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目&#xff0c;叫 skills4/skills &#xff0c;它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景&#xff1a;一个旨在展示或教授某种技能的仓库&#xff0c;本身却成了安…

2026/7/5 0:01:08阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示&#xff1a;因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战&#xff1a;从“黑箱预测”到“可信推理”2026年6月&#xff0c;第7届机器学习与趋势国际会议&#xff08;MLT 2026&#xff09;将在悉尼召开。会议议程中&#xff0c;“因果与可解释机器学习…

2026/7/5 0:01:08阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时&#xff0c;通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中&#xff0c;是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/5 0:01:08阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时&#xff0c;发现推理速度只有可怜的 1-2 FPS&#xff0c;而别人的演示视频却能跑到 30 FPS 以上&#xff0c;那么问题很可能不在模型本身&#xff0c;而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后&#xff0c;会直接使用官方示例…

2026/7/5 1:30:27阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一&#xff1a;为什么你需要了解 Coze 和 Dify&#xff1f;如果你对 AI 应用开发感兴趣&#xff0c;但一看到“大模型”、“智能体”、“工作流”这些词就头疼&#xff0c;觉得门槛太高&#xff0c;那这篇文章就是为你准备的。很多开发者&#xff0c;包括我自己&#…

2026/7/5 3:48:10阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会&#xff1a;配图一直是个让人头疼的问题。2026年&#xff0c;AI生图工具已经非常成熟了&#xff0c;但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1&#xff1a;速度之王2026年6月11日&#xff0c…

2026/7/5 3:48:09阅读更多 →