qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果

article/2025/11/3 15:38:09

应大家的要求,还是把完整的工程文件贴出来,大家省点事:http://www.kuaipan.cn/file/id_48923272389086450.htm

先看看运行效果,我用的群创7寸屏,主机是mini2440,分辨率是800*480,程序写比较粗糙,但对初学者还是有一点启发,大家一起进步。

qt中提供了QGphicsView,QGraphicsScene,QGraphicsItem,QGraphicsPixmapItem是QGraphicsItem的子类

分辨创建它们的实例:view,scene,item,然后通过各自的方法scene->addItem(item);view->setScene(scene);就可以达到类似下图的效果,想要进一步定制,则要继承QGraphicsItem或QGraphicsPixmapItem,然后重写paint()、boundingRect()等方法,此外如果还想要获取鼠标事件,重写mousePressEvent等事件就好了,注意,一旦重写了mousePressEvent方法,就以为了qt不会再自动处理item的任何press事件了,可以在你重写的mousePressEvent方法中最后添加QGraphicsItem::mousePressEvent(event);解决这个问题,就是说你获取到了鼠标事件,但是依然让qt处理这个鼠标事件。

程序中的item可以水平拖动,拖动的同时图标大小会渐变,中间最大,两边渐小。

图1


图2


图3



下面是源程序目录结构:


mainwindow.h与main.cpp是qt自动产生的代码,我没有产生窗口ui

myscene.h与某与scene.cpp是定义了类MyScene,继承自QGraphicsScene,我的目的是要获取其鼠标事件

nodeui.h与nodeui.cpp是定义了类NodeUI,继承自QGraphicsPixmapItem,目的相当多。

下面具体的源文件:myscene.h与myscene.cpp相对简单,就实现了一个功能

myscene.h

#ifndef MYSCENE_H
#define MYSCENE_H#include <QGraphicsScene>class MyScene : public QGraphicsScene
{
Q_OBJECT
public:explicit MyScene(QObject *parent = 0);private:void mouseMoveEvent(QGraphicsSceneMouseEvent *event);void mousePressEvent(QGraphicsSceneMouseEvent *event);void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);signals:void isMoving(QPointF &pos);public slots:private:QPointF  beforePos;QPointF  releasePos;
};#endif // MYSCENE_H

myscene.cpp

#include "myscene.h"
#include <QGraphicsSceneMouseEvent>
#include <QPointF>
#include <QDebug>MyScene::MyScene(QObject *parent) :QGraphicsScene(parent)
{
}
void MyScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{//QPointF pos = event->scenePos();QPointF pos(event->scenePos().x()-beforePos.x(),event->scenePos().y()-beforePos.y());emit isMoving(pos);//qDebug()<<"x:"<<pos.x()<<"y:"<<pos.y();
}
void MyScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{beforePos = event->scenePos();
}
void MyScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{releasePos = event->scenePos();
}

再看nodeui.h与nodeui.cpp,在原来的QGraphicsPixmapItem基础上又假如了点自己的东西

#ifndef NODEUI_H
#define NODEUI_H#include <QGraphicsPixmapItem>
#include <QGraphicsItem>
#include <QStyleOptionGraphicsItem>
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QPointF>class NodeUI : public QObject,public QGraphicsPixmapItem
{Q_OBJECT
public:NodeUI();NodeUI(QString &file,QString &text,int imagesize=80);//setup functionvoid setMyPixmap(QString &file,int size);void setMyText(QString &text);QString getMyText();//virtual functionQRectF boundingRect() const;QPainterPath shape() const;
signals:void nodeIsMoving(QPointF &pos);void nodeIsPressed();protected:void mousePressEvent(QGraphicsSceneMouseEvent *event);void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
private://QString myImage;QString myText;};#endif // NODEUI_H

nideui.cpp

#include "nodeui.h"
#include <QPixmap>
#include <iostream>
#include <QDebug>NodeUI::NodeUI()
{
}
/*note: imagesize = 80 is in the nodeui.h*/
NodeUI::NodeUI(QString &file,QString &text,int imagesize)
{setMyText(text);setMyPixmap(file,imagesize);
}void NodeUI::setMyText(QString &text)
{myText = text;
}void NodeUI::setMyPixmap(QString &file,int size)
{//myImage = file;QPixmap pixmap;pixmap.load(file);pixmap= pixmap.scaled(size,size,Qt::IgnoreAspectRatio, Qt::SmoothTransformation);setPixmap(pixmap);
}
QRectF NodeUI::boundingRect() const
{QRect rect = this->pixmap().rect();//return QRectF(rect);return QRectF(0,0,rect.width(),rect.width()+15);
}void NodeUI::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
{QPixmap pixmap = this->pixmap();QRect rect = pixmap.rect();painter->drawPixmap(rect,pixmap);//print name,calculate the text's heigh & width for center layoutQPen pen(Qt::black);painter->setPen(pen);painter->setRenderHint(QPainter::Antialiasing);QFont font("Verdana",8, QFont::Normal);painter->setFont(font);painter->drawText(QRectF(0,rect.height(),rect.width(),15),Qt::AlignCenter,myText);if (option->state & QStyle::State_Sunken){QRectF rect1 = boundingRect();//QPen pen(Qt::darkGreen);painter->setPen(QPen(Qt::darkGreen));}else{}
}
QPainterPath NodeUI::shape() const
{QRectF rect = boundingRect();QPainterPath path;path.addRoundRect(rect, 5,5);return path;
}void NodeUI::mousePressEvent(QGraphicsSceneMouseEvent *event)
{emit nodeIsPressed();qDebug()<<"pressed";QGraphicsItem::mousePressEvent(event);
}
void NodeUI::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{update(boundingRect());QGraphicsItem::mouseReleaseEvent(event);
}
QString NodeUI::getMyText()
{return myText;
}

最后是scene与item的文件mainwindow.cpp,继承了QMainWindow,作用就是画一个应用程序框架

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QtGui/QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QPointF>
#include "nodeui.h"
#include "myscene.h"
#include <QMap>class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = 0);~MainWindow();NodeUI *selectedNodeUI();bool isNodeUiClicked();void nodeUiSizeAdjust();//varprotected:private:void GetScreenInfo();QGraphicsView *view;//QGraphicsScene *scene;MyScene *scene;//instead of (NodeUI *nodeui;)&(QPointF nodeUiPos;)//目前弃用,由于QMap的顺序无法人为设定,按照内部key自动升序//QMap<NodeUI*,QPointF>nodeUiMaps;//NodeUI *currentNodeUI;//nodeui pressed or releasedvolatile bool mPressed;QList<NodeUI*> nodeUiLists;QList<QPointF> nodeUiPosLists;QList<QPixmap> nodeUiPixmapLists;
/*struct {QList<NodeUI*> nodelists;QList<QPointF> poslists;}ss;*///弃用NodeUI *nodeui;QPointF nodeUiPos;//sceen size info;qint16 sceenSizeX;qint16 sceenSizeY;
private slots:void isMoving(QPointF &pos);void isPressed();void isReleased();void selectionChanged();signals:void nodeUiClicked(NodeUI* node);
};#endif // MAINWINDOW_H
mainwindow.cpp

#include "mainwindow.h"
#include <QDesktopWidget>
#include <QApplication>
#include <QPixmap>
#include <QGraphicsItem>
#include <QMouseEvent>
#include <QWidget>
#include <QGraphicsPixmapItem>
#include <QMessageBox>
#include <QDebug>const qreal MY_NODEUI_POS_Y = 200;
const qreal MY_NODEUI_DIS = 110;
const qreal MY_NODEUI_STA = 90;
const int   MYNODEUI_SIZE = 100;
const int   MYNODEUI_SIZE_M = 20;
const int   SCREEN_SIZE = 800;
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{//初始化mPressed = false;//get windows sizeGetScreenInfo();view = new QGraphicsView;scene = new MyScene();scene->setSceneRect(0,0,800,480);//newQString file;QString text;QPointF pos;NodeUI* node;//HOME:1file = QString(":/images/home.png");text = QString("Home");pos = QPointF(MY_NODEUI_STA,MY_NODEUI_POS_Y);node = new NodeUI(file,text,MYNODEUI_SIZE);node->setPos(pos);nodeUiLists.append(node);nodeUiPosLists.append(pos);nodeUiPixmapLists.append(node->pixmap());/*here cannot delete node!!!!!!!!!!!!!!!delete node;*///VIDIO:2file = QString(":/images/securitycamera.png");text = QString("Vidio");pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*1,MY_NODEUI_POS_Y);node = new NodeUI(file,text,MYNODEUI_SIZE);node->setPos(pos);nodeUiLists.append(node);nodeUiPosLists.append(pos);nodeUiPixmapLists.append(node->pixmap());//APPLICATION:3file = QString(":/images/application.png");text = QString("Application");pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*2,MY_NODEUI_POS_Y);node = new NodeUI(file,text,MYNODEUI_SIZE);node->setPos(pos);nodeUiLists.append(node);nodeUiPosLists.append(pos);nodeUiPixmapLists.append(node->pixmap());//NETWORK:4file = QString(":/images/network-2.png");text = QString("Network");pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*3,MY_NODEUI_POS_Y);node = new NodeUI(file,text,MYNODEUI_SIZE);node->setPos(pos);nodeUiLists.append(node);nodeUiPosLists.append(pos);nodeUiPixmapLists.append(node->pixmap());//COMPUTER:5file = QString(":/images/smartphone.png");text = QString("Phone");pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*4,MY_NODEUI_POS_Y);node = new NodeUI(file,text,MYNODEUI_SIZE);node->setPos(pos);nodeUiLists.append(node);nodeUiPosLists.append(pos);nodeUiPixmapLists.append(node->pixmap());//CUSTOMIZE:5file = QString(":/images/customize.png");text = QString("Setting");pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*5,MY_NODEUI_POS_Y);node = new NodeUI(file,text,MYNODEUI_SIZE);node->setPos(pos);nodeUiLists.append(node);nodeUiPosLists.append(pos);nodeUiPixmapLists.append(node->pixmap());//重新计算UiSizenodeUiSizeAdjust();int i = 0;foreach(NodeUI* node_temp,nodeUiLists){node_temp->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);qDebug()<<"name:"<<node_temp->getMyText()<<nodeUiPosLists.at(i);scene->addItem(node_temp);i++;}//用于按钮的单机view->setScene(scene);//set drag mode//view->setDragMode(QGraphicsView::RubberBandDrag);view->setRenderHints(QPainter::Antialiasing);//no menuview->setContextMenuPolicy(Qt::NoContextMenu);view->setBackgroundBrush(QImage(":/images/shuibo2.jpg"));//view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);//view->setCacheMode(QGraphicsView::CacheBackground);setCentralWidget(view);setWindowTitle(tr("Main Window"));
}
//槽,当scene鼠标拖拽是执行
//控制UI图标的水平
void MainWindow::isMoving(QPointF &pos)
{int i=0;if(mPressed){foreach(NodeUI* node,nodeUiLists){node->setPos(nodeUiPosLists.at(i).x()+pos.x(),MY_NODEUI_POS_Y);i++;}nodeUiSizeAdjust();}
}
//槽,当nodeui鼠标按下时执行,调用selectedNodeUI函数,更新currentNodeUI变量
//除此之外,selectionChanged()也是一个槽,由scene调用
void MainWindow::isPressed()
{selectionChanged();mPressed = true;
}
//槽,当nodeui鼠标释放时执行
//应当设置标志位,让UI图片停止对鼠标拖动事件的响应
void MainWindow::isReleased()
{mPressed = false;if(isNodeUiClicked())qDebug()<<"clicked";qDebug()<<"release";
}//槽,当scene的selectedItem变化时,发送同名信号到此槽
void MainWindow::selectionChanged()
{int i=0,j=0;QList<QGraphicsItem *> items = scene->selectedItems();if (items.count() == 1) {//当前所选择的UI图标的坐标QPointF pos = items.first()->pos();NodeUI* node_temp = dynamic_cast<NodeUI *>(items.first());qDebug()<<"items.x:"<<pos.x()<<"items.y:"<<pos.y();foreach(NodeUI* node,nodeUiLists){if(node == node_temp)break;i++;}j=i;i=0;foreach(QPointF ppos,nodeUiPosLists){nodeUiPosLists[i].setX((i-j)*MY_NODEUI_DIS+pos.x());nodeUiPosLists[i].setY(MY_NODEUI_POS_Y);i++;}} else {return;}
}
//判断是否Nodeui接收的是否是单击信号。
//判断依据是当前单击的nodeui对象的pos与存储在nodeUiPosListsd的位置比较,相等则为单击
bool MainWindow::isNodeUiClicked()
{int i=-1;QList<QGraphicsItem *> items = scene->selectedItems();if (items.count() == 1) {QPointF pos = items.first()->pos();NodeUI* node_temp = dynamic_cast<NodeUI *>(items.first());if(pos ==nodeUiPosLists.at(i)){//emit nodeUiClicked(node_temp);QMessageBox::information(this,"New Window","will open : "+node_temp->getMyText());return true;}}return false;
}
void MainWindow::nodeUiSizeAdjust()
{quint16 i=0;foreach(NodeUI* node,nodeUiLists){//qDebug()<<"i= "<<i;QPointF pos=node->pos();pos.setX(node->pos().x()+MYNODEUI_SIZE/2);//pos.setX(node->pos().x()+node->pixmap().width());if(pos.x()>=0 && pos.x()<=SCREEN_SIZE/2){//(MYNODEUI_SIZE-MYNODEUI_SIZE_M)/(SCREEN_SIZE/2)==(size-20)/pos.x()quint16 size=pos.x()/5+20;QPixmap pixmap = nodeUiPixmapLists.at(i);//QPixmap pixmap = nodeUiLists.at(i)->pixmap();pixmap = pixmap.scaled(size,size,Qt::IgnoreAspectRatio, Qt::SmoothTransformation);nodeUiLists[i]->setPixmap(pixmap);}//if(pos.x()>SCREEN_SIZE/2 && pos.x()<=SCREEN_SIZE)if(pos.x()>SCREEN_SIZE/2 && pos.x()<=SCREEN_SIZE+10){//(MYNODEUI_SIZE-MYNODEUI_SIZE_M)/(SCREEN_SIZE/2)==(size-20)/pos.x()quint16 size=(SCREEN_SIZE-pos.x())/5+20;QPixmap pixmap = nodeUiPixmapLists.at(i);//QPixmap pixmap = nodeUiLists.at(i)->pixmap();pixmap = pixmap.scaled(size,size,Qt::IgnoreAspectRatio, Qt::SmoothTransformation);nodeUiLists[i]->setPixmap(pixmap);}i++;}
}
MainWindow::~MainWindow()
{
}
//获取设备分辨率的呢个信息
void MainWindow::GetScreenInfo()
{QDesktopWidget* desktopWidget = QApplication::desktop();//获取可用桌面大小//QRect deskRect = desktopWidget->availableGeometry();//获取设备屏幕大小QRect screenRect = desktopWidget->screenGeometry();sceenSizeX = screenRect.width();sceenSizeY = screenRect.height();//获取系统设置的屏幕个数(屏幕拷贝方式该值为1)//g_nScreenCount = desktopWidget->screenCount();
}
最后是main.cpp

实例化MainWindow

#include <QtGui/QApplication>
#include "mainwindow.h"int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.setWindowOpacity(1);w.setWindowFlags(Qt::FramelessWindowHint);w.setAttribute(Qt::WA_TranslucentBackground);w.show();//w.showFullScreen();return a.exec();
}

大概都写了注解了,其实看看一个名称也该大概了解其作用,写这程序时遇到的问题都记录在了前一篇qt学习笔记(四)中,记录一下,以备不时之需


http://chatgpt.dhexx.cn/article/RYiaeMdn.shtml

相关文章

Qt QGraphicsScene、QGraphicsView类实现仪表盘

Qt QGraphicsScene、QGraphicsView类实现仪表盘 【1】UI界面设计【2】效果【3】QGraphicsScene简介【4】QGraphicsEllipseItem简介【5】QGraphicsPolygonItem简介【6】QGraphicsLineItem简介【7】QGraphicsView简介【8】仪表源码头文件源码 【1】UI界面设计 【2】效果 【3】QGr…

qt QGraphicsScene 简单例子

坐标 graphicsView是Widget这个界面的子控件&#xff0c; 他的位置是左上角坐标为&#xff08;30,30&#xff09; 他的宽度为431&#xff0c;高度为431. 如果在graphicsView 这个子控件中&#xff0c; 继续加入 子控件A&#xff0c;由于graphicsView比较特殊。 根据它的align…

QGraphicsScene设置SceneRect

简要说明 QGraphicsScene场景区域&#xff0c;可在构造QGraphicsScene对象时设定&#xff0c;也可通过函数setSceneRect设定。QGraphicsScene场景区域中坐标原点的位置&#xff0c;会影响到图形项的坐标设定&#xff0c;进而影响图形项在场景中的显示位置。以将图片显示在中心…

QT QGraphicsScene / QGraphicsView中 sceneRect 使用详细说明

接触QT不久&#xff0c;发现QT的Graphics View框架坐标使用和平常不一样&#xff0c;尤其sceneRect的作用。 官方文档关于这部分介绍真是蛋疼&#xff0c;网上说的也寥寥。没法自己研究了一下&#xff0c;其实这块内容QT设计的很方便&#xff0c;只是文档讲解的太烂&#xff0c…

【QT】GraphicsView、QGraphicsScene、QGraphicsEllipseItem的使用

GraphicsView、QGraphicsScene、QGraphicsEllipseItem的使用 前言实验目的重构GraphicsView类新建GraphicsView、QGraphicsScene层绘制Item图形控件绘制圆形绘制矩形绘制三角形绘制文字绘制直线 组合、打散、前置和后置组合打散控件前置控件后置 绑定功能事件总结 前言 对于绘…

Qt 绘图之QGraphicsScene QGraphicsView QGraphicsItem详解

Graphics View提供了一个界面&#xff0c;它既可以管理大数量的定制2D graphical items&#xff0c;又可与它们交互&#xff0c;有一个view widget可以把这些项绘制出来&#xff0c;并支持旋转与缩放。这个柜架也包含一个事件传播结构&#xff0c;对于在scene中的这些items,它具…

PyQt5:QGraphicsScene入门一:基本介绍、场景定义、添加元素

为什么80%的码农都做不了架构师?>>> 简介说明: 这个QGraphicsScene类用于在场景中操作大量的2D图形元素,这个类是作为一个容器QGraphicsItems存在的,它是连同QGraphicsView用于可视化的二维表面的图形项目,如直线,矩形,文本,甚至定制物品;还可以有效地…

QGraphicsView,QGraphicsScene和QGraphicsItem

图形视图框架提供了一个基于图形项的模型视图编程方法&#xff0c;主要由场景、视图和图形项三部分组成&#xff0c;这三部分分别由QGraphicsScene、QGraphicsView和QGraphicsItem这三个类来表示。 场景QGraphicsScene QGraphicsScene类提供绘图场景&#xff08;Scene&#…

Qt图形视图框架:QGraphicsScene详解

一、描述 1、场景提供了一个用于管理大量2D图形项的平面。该类充当图形项的容器。 它与视图一起用于可视化2D曲面上的图形图形项。 2、场景没有自己的视觉外观&#xff0c;只负责管理图形项。 3、场景的最大优势之一就是其快速有效地定位图形项的能力。即使场景中有数百万个…

Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/117660217 长期持续带来更多项目与技术分享&#xff0c;咨询请加QQ:21497936、微信&#xff1a;yangsir198808 红胖子(红模仿)的博文大全&#xff1…

TLS、SSL原理解析

TLS、SSL https协议就是建立在TLS、SSL之上的。

SSL证书原理讲解

SSL证书原理讲解 - 2240930501 - 博客园一直以来都对数字证书的签发&#xff0c;以及信任等事情一知半解。总算有个闲适的周末来总结和深入一下相关的知识。 CA: CA(Certificate Authority)是证书的签发机构&#xff0c;它是负责管理和签发证书的https://www.cnblogs.com/dingl…

浅谈SSL/TLS工作原理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 浅谈SSL/TLS工作原理 SSL对称加密非对称加密定义工作过程特点及性能分析非对称加密常用算法举例 非对称加密和对称加密各自有啥优缺点&#xff1f;CA&#xff08;Certificate…

SSL工作原理介绍以及java实现

SSL工作原理介绍以及java实现 目录 SSL工作原理介绍以及java实现 SSL简介SSL工作原理 握手协议Handshake protocol 1握手阶段使用RSA加密算法2握手阶段使用Diffie-Hellman加密算法记录协议Record protocol警报协议Alert protocolWireshark抓包图解java实现Secure Sockets Laye…

SSL证书原理是什么?ssl证书工作流程是什么

SSL证书的运用促使网址更加安全性&#xff0c;做为一种加密传输协议书技术性。SSL的挥手协议书让顾客和集群服务器进行彼此之间的身份验证。为了让各位能进一步了解ssl证书&#xff0c;小编来向各位介绍SSL证书原理。 SSL证书原理如下&#xff1a; ①手机客户端向网络服务器恳…

SSL 工作原理

博客引用处&#xff08;以下内容在原有博客基础上进行补充或更改&#xff0c;谢谢这些大牛的博客指导&#xff09;&#xff1a; SSL工作原理 首先说明下SSL工作原理&#xff1a; 1.1 产生背景 基于万维网的电子商务和网上银行等新兴应用&#xff0c;极大地方便了人们的日常生活…

SSL原理介绍

SSL原理介绍 SSL——安全套接字层&#xff08;Secure Sockers Layer&#xff09;协议由著名的Netscape公司开发。为了保证通信双方建立安全可靠的传输隧道&#xff0c;SSL使用PKI中的数字证书技术对通信双方进行身份认证&#xff1b;使用对称加密来保证数据保密性&#xff1b;使…

ssl 原理和建立连接过程

ssl 与http关系 ssl (“Secure Sockets Layer”)加密原理 和https的关系 https http ssl ssl 位置&#xff1a; SSL握手 证书主要作用是在SSL握手中&#xff0c;我们来看一下SSL的握手过程 客户端提交https请求服务器响应客户&#xff0c;并把证书公钥发给客户端客户端验…

SSL/TLS 的工作原理

HTTPS 之所以能达到较高的安全性要求,就是结合了 SSL/TLS 和 TCP 协议,对通信数据进行加密,解决了 HTTP 数据透明的问题。接下来重点介绍一下 SSL/TLS 的工作原理。 SSL 和 TLS 的区别? SSL 和 TLS 没有太大的区别。 SSL 指安全套接字协议(Secure Sockets Layer),首次…

SSL工作原理

公钥和私钥 一直以来对公钥和私钥都理解得不是很透彻&#xff0c;感觉到模棱两可。今天在网上找了半天&#xff0c;通过查看对这个密钥对的理解&#xff0c;总算弄清楚了。 公钥和私钥就是俗称的不对称加密方式&#xff0c;是从以前的对称加密&#xff08;使用用户名与…