IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> [PyQt5-Node-Editor][基础篇]从零开始使用Pyqt5制作节点编辑器(13)——框选与多选 -> 正文阅读

[C++知识库][PyQt5-Node-Editor][基础篇]从零开始使用Pyqt5制作节点编辑器(13)——框选与多选

目标

按住shift键可以进行多选

在这里插入图片描述

在背景上按住左键可以框选

在这里插入图片描述

shift+框选也能实现多选接力

在这里插入图片描述

实现

将setStyleSheet功能从NODE移动到主页

为了方便view里面的控件样式设计,需要将NODE移动到main程序里执行

class NodeEditWind(QMainWindow,Ui_MainWindow):
    def __init__(self,parent=None):
        super(NodeEditWind,self).__init__(parent)
        self.setupUi(self)


        #create graphics scene
        self.scene = Scene()
        self.grScene = self.scene.grScene

        self.addNode()

        # create graphics view
        self.view = QDMGraphicsView(self.grScene,self)
        self.Layout_node.addWidget(self.view)

        #set QSS
        self.stylesheet_filename = 'qss/nodestyle.qss'
        self.loadStylesheet(self.stylesheet_filename)
        
    def loadStylesheet(self, filename):
        print('STYLE loading', filename)
        file = QFile(filename)
        file.open(QFile.ReadOnly | QFile.Text)
        stylesheet = file.readAll()
        QApplication.instance().setStyleSheet(str(stylesheet, encoding='utf-8'))

		

增加shift多选功能

首先在鼠标左键按下添加新的按下逻辑判断

    def leftMouseButtonPress(self, event):

        item = self.getItemAtClick(event)

        self.last_lmb_click_scene_pos = self.mapToScene(event.pos())
		
		#比之前就加了这个if下的几行代码
        if hasattr(item, "node") or isinstance(item, QDMGraphicsEdge) or item is None:
            if event.modifiers() & Qt.ShiftModifier:
                event.ignore()
                fakeEvent = QMouseEvent(QEvent.MouseButtonPress, event.localPos(), event.screenPos(),
                                        Qt.LeftButton, event.button() | Qt.LeftButton,
                                        event.modifiers() | Qt.ControlModifier)
                super().mousePressEvent(fakeEvent)
                return

        if type(item) is QDMGraphicsSocket:
            if self.mode == MODE_NOOP:
                self.mode = MODE_EDGE_DRAG
                self.edgeDragStart(item)
                return

        if self.mode == MODE_EDGE_DRAG:
            res = self.edgeDragEnd(item)
            if res: return

        super().mousePressEvent(event)

其中hasattr是判断选中项是否为node,isinstance是判断选中项是否为QDMGraphicsEdge对象,最后一个点空白处框选

Qt.ShiftModifier检测是否按下shift,而众所周知的是,在windows系统下,使用crtl加上鼠标左键可以完成多选,我们需要使用shit来替代ctrl的功能,所以需要设置一个fakeEvent来让鼠标事件变为左键+crtl事件

为了使view能使用框选功能,需要在view的init里增加新的代码

self.setDragMode(QGraphicsView.RubberBandDrag)

当然,为了在不同的操作系统中拥有相同的显示效果,我们需要在QSS做新的定义

QDMNodeContentWidget {background: transparent; }
QDMNodeContentWidget QLabel {color: #e0e0e0;}
QGraphicsView {selection-background-color: rgb(255,255,255);}

接着就是鼠标松开事件
与鼠标左键同理,这里只贴增加的代码

        if hasattr(item, "node") or isinstance(item, QDMGraphicsEdge) or item is None:
            if event.modifiers() & Qt.ShiftModifier:
                event.ignore()
                fakeEvent = QMouseEvent(event.type(), event.localPos(), event.screenPos(),
                                        Qt.LeftButton, Qt.NoButton,
                                        event.modifiers() | Qt.ControlModifier)
                super().mouseReleaseEvent(fakeEvent)
                return

在多选后,用鼠标左键拖动,就可以带动全部节点拖动
但是会发现有的Edge不随NODE移动,这是一个显示BUG,需要修复

显示BUG修复

为什么会有这个BUG,是因为node的刷新机制的问题,要解决这个问题,需要保证每个node移动的时候,edge都进行了刷新
除了这个BUG,还有一个BUG,就是选中标题时会导致多选取消,这是因为标题没有"node"这个属性,我们需要在node_graphics_node.py中的

def initTitle(self):

添加

self.title_item.node = self.node

使其也与本体指向同一个NODE属性

首先需要能保证移动一个node的时候能完成整个node的遍历,于是需要
进入node_graphics_node.py
将鼠标移动代码修改为如下

    def mouseMoveEvent(self, event):
        super().mouseMoveEvent(event)

        # 更新被选择NODE的EAGE
        for node in self.scene().scene.nodes:
            if node.grNode.isSelected():
                node.updateConnectedEdges()

for node in self.scene().scene.nodes:用于遍历
if node.grNode.isSelected():判断节点是否被选中,选中的更新,没被选中的不更新

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-15 15:59:28  更:2021-07-15 16:00:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/19 20:07:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码