mirror of
https://github.com/rbreu/beeref.git
synced 2026-03-11 08:54:28 +00:00
为items.py添加中文注释
This commit is contained in:
parent
21c27f77e8
commit
5422100160
1 changed files with 259 additions and 259 deletions
518
beeref/items.py
518
beeref/items.py
|
|
@ -446,293 +446,293 @@ class BeePixmapItem(BeeItemMixin, QtWidgets.QGraphicsPixmapItem): # 定义一个
|
|||
painter.setPen(pen) # 设置画笔为黑色虚线画笔对象
|
||||
painter.drawRect(rect) # 绘制项的裁剪区域矩形
|
||||
|
||||
def paint(self, painter, option, widget):
|
||||
if abs(painter.combinedTransform().m11()) < 2:
|
||||
def paint(self, painter, option, widget): # 定义项的绘制方法,用于绘制项
|
||||
if abs(painter.combinedTransform().m11()) < 2: # 检查缩放比例是否小于2倍
|
||||
# We want image smoothing, but only for images where we
|
||||
# are not zoomed in a lot. This is to ensure that for
|
||||
# example icons and pixel sprites can be viewed correctly.
|
||||
painter.setRenderHint(painter.RenderHint.SmoothPixmapTransform)
|
||||
painter.setRenderHint(painter.RenderHint.SmoothPixmapTransform) # 设置图像平滑渲染提示
|
||||
|
||||
if self.crop_mode:
|
||||
self.paint_debug(painter, option, widget)
|
||||
if self.crop_mode: # 如果处于裁剪模式
|
||||
self.paint_debug(painter, option, widget) # 绘制调试信息
|
||||
|
||||
# Darken image outside of cropped area
|
||||
painter.drawPixmap(0, 0, self.pixmap())
|
||||
path = QtWidgets.QGraphicsPixmapItem.shape(self)
|
||||
path.addRect(self.crop_temp)
|
||||
color = QtGui.QColor(0, 0, 0)
|
||||
color.setAlpha(100)
|
||||
painter.setBrush(QtGui.QBrush(color))
|
||||
painter.setPen(Qt.PenStyle.NoPen)
|
||||
painter.drawPath(path)
|
||||
painter.setBrush(QtGui.QBrush())
|
||||
painter.drawPixmap(0, 0, self.pixmap()) # 绘制完整图像
|
||||
path = QtWidgets.QGraphicsPixmapItem.shape(self) # 获取项目形状路径
|
||||
path.addRect(self.crop_temp) # 向路径添加临时裁剪矩形
|
||||
color = QtGui.QColor(0, 0, 0) # 创建黑色
|
||||
color.setAlpha(100) # 设置透明度
|
||||
painter.setBrush(QtGui.QBrush(color)) # 设置画刷
|
||||
painter.setPen(Qt.PenStyle.NoPen) # 设置无笔
|
||||
painter.drawPath(path) # 绘制路径(使裁剪区域外变暗)
|
||||
painter.setBrush(QtGui.QBrush()) # 重置画刷
|
||||
|
||||
for handle in self.crop_handles():
|
||||
self.draw_crop_rect(painter, handle())
|
||||
self.draw_crop_rect(painter, self.crop_temp)
|
||||
else:
|
||||
pm = self._grayscale_pixmap if self.grayscale else self.pixmap()
|
||||
painter.drawPixmap(self.crop, pm, self.crop)
|
||||
self.paint_selectable(painter, option, widget)
|
||||
for handle in self.crop_handles(): # 遍历所有裁剪手柄
|
||||
self.draw_crop_rect(painter, handle()) # 绘制裁剪手柄矩形
|
||||
self.draw_crop_rect(painter, self.crop_temp) # 绘制临时裁剪矩形
|
||||
else: # 非裁剪模式
|
||||
pm = self._grayscale_pixmap if self.grayscale else self.pixmap() # 根据灰度模式选择像素图
|
||||
painter.drawPixmap(self.crop, pm, self.crop) # 绘制裁剪区域
|
||||
self.paint_selectable(painter, option, widget) # 绘制选择效果
|
||||
|
||||
def enter_crop_mode(self):
|
||||
logger.debug(f'Entering crop mode on {self}')
|
||||
self.prepareGeometryChange()
|
||||
self.crop_mode = True
|
||||
self.crop_temp = QtCore.QRectF(self.crop)
|
||||
self.crop_mode_move = None
|
||||
self.crop_mode_event_start = None
|
||||
self.grabKeyboard()
|
||||
self.update()
|
||||
self.scene().crop_item = self
|
||||
def enter_crop_mode(self): # 进入裁剪模式
|
||||
logger.debug(f'Entering crop mode on {self}') # 记录进入裁剪模式的日志
|
||||
self.prepareGeometryChange() # 通知Qt几何形状将要改变
|
||||
self.crop_mode = True # 启用裁剪模式
|
||||
self.crop_temp = QtCore.QRectF(self.crop) # 复制当前裁剪区域作为临时裁剪区域
|
||||
self.crop_mode_move = None # 初始化裁剪移动类型
|
||||
self.crop_mode_event_start = None # 初始化裁剪事件起始位置
|
||||
self.grabKeyboard() # 抓取键盘输入
|
||||
self.update() # 更新项目显示
|
||||
self.scene().crop_item = self # 设置场景的当前裁剪项目
|
||||
|
||||
def exit_crop_mode(self, confirm):
|
||||
logger.debug(f'Exiting crop mode with {confirm} on {self}')
|
||||
if confirm and self.crop != self.crop_temp:
|
||||
self.scene().undo_stack.push(
|
||||
def exit_crop_mode(self, confirm): # 退出裁剪模式,参数confirm表示是否确认裁剪
|
||||
logger.debug(f'Exiting crop mode with {confirm} on {self}') # 记录退出裁剪模式的日志
|
||||
if confirm and self.crop != self.crop_temp: # 如果确认且裁剪区域有变化
|
||||
self.scene().undo_stack.push( # 将裁剪操作添加到撤销栈
|
||||
commands.CropItem(self, self.crop_temp))
|
||||
self.prepareGeometryChange()
|
||||
self.crop_mode = False
|
||||
self.crop_temp = None
|
||||
self.crop_mode_move = None
|
||||
self.crop_mode_event_start = None
|
||||
self.ungrabKeyboard()
|
||||
self.update()
|
||||
self.scene().crop_item = None
|
||||
self.prepareGeometryChange() # 通知Qt几何形状将要改变
|
||||
self.crop_mode = False # 禁用裁剪模式
|
||||
self.crop_temp = None # 清除临时裁剪区域
|
||||
self.crop_mode_move = None # 清除裁剪移动类型
|
||||
self.crop_mode_event_start = None # 清除裁剪事件起始位置
|
||||
self.ungrabKeyboard() # 释放键盘抓取
|
||||
self.update() # 更新项目显示
|
||||
self.scene().crop_item = None # 清除场景的当前裁剪项目
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
if event.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
|
||||
self.exit_crop_mode(confirm=True)
|
||||
elif event.key() == Qt.Key.Key_Escape:
|
||||
self.exit_crop_mode(confirm=False)
|
||||
else:
|
||||
super().keyPressEvent(event)
|
||||
def keyPressEvent(self, event): # 键盘按键事件处理
|
||||
if event.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter): # 如果按下Enter键
|
||||
self.exit_crop_mode(confirm=True) # 确认并退出裁剪模式
|
||||
elif event.key() == Qt.Key.Key_Escape: # 如果按下Escape键
|
||||
self.exit_crop_mode(confirm=False) # 取消并退出裁剪模式
|
||||
else: # 其他按键
|
||||
super().keyPressEvent(event) # 调用父类处理
|
||||
|
||||
def hoverMoveEvent(self, event):
|
||||
if not self.crop_mode:
|
||||
return super().hoverMoveEvent(event)
|
||||
def hoverMoveEvent(self, event): # 鼠标悬停移动事件处理
|
||||
if not self.crop_mode: # 如果不是裁剪模式
|
||||
return super().hoverMoveEvent(event) # 调用父类处理
|
||||
|
||||
for handle in self.crop_handles():
|
||||
if handle().contains(event.pos()):
|
||||
self.set_cursor(self.get_crop_handle_cursor(handle))
|
||||
for handle in self.crop_handles(): # 遍历所有裁剪手柄
|
||||
if handle().contains(event.pos()): # 如果鼠标在手柄内
|
||||
self.set_cursor(self.get_crop_handle_cursor(handle)) # 设置对应的光标
|
||||
return
|
||||
for edge in self.crop_edges():
|
||||
if edge().contains(event.pos()):
|
||||
self.set_cursor(self.get_crop_edge_cursor(edge))
|
||||
for edge in self.crop_edges(): # 遍历所有裁剪边缘
|
||||
if edge().contains(event.pos()): # 如果鼠标在边缘内
|
||||
self.set_cursor(self.get_crop_edge_cursor(edge)) # 设置对应的光标
|
||||
return
|
||||
self.unset_cursor()
|
||||
self.unset_cursor() # 重置光标
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
if not self.crop_mode:
|
||||
return super().mousePressEvent(event)
|
||||
def mousePressEvent(self, event): # 鼠标按下事件处理
|
||||
if not self.crop_mode: # 如果不是裁剪模式
|
||||
return super().mousePressEvent(event) # 调用父类处理
|
||||
|
||||
event.accept()
|
||||
for handle in self.crop_handles():
|
||||
event.accept() # 接受事件
|
||||
for handle in self.crop_handles(): # 遍历所有裁剪手柄
|
||||
# Click into a handle?
|
||||
if handle().contains(event.pos()):
|
||||
self.crop_mode_event_start = event.pos()
|
||||
self.crop_mode_move = handle
|
||||
if handle().contains(event.pos()): # 如果点击位置在手柄内
|
||||
self.crop_mode_event_start = event.pos() # 记录事件起始位置
|
||||
self.crop_mode_move = handle # 设置移动类型为该手柄
|
||||
return
|
||||
for edge in self.crop_edges():
|
||||
for edge in self.crop_edges(): # 遍历所有裁剪边缘
|
||||
# Click into an edge handle?
|
||||
if edge().contains(event.pos()):
|
||||
self.crop_mode_event_start = event.pos()
|
||||
self.crop_mode_move = edge
|
||||
if edge().contains(event.pos()): # 如果点击位置在边缘内
|
||||
self.crop_mode_event_start = event.pos() # 记录事件起始位置
|
||||
self.crop_mode_move = edge # 设置移动类型为该边缘
|
||||
return
|
||||
# Click not in handle, end cropping mode:
|
||||
# Click not in handle, end cropping mode: 如果点击不在手柄或边缘上,结束裁剪模式
|
||||
self.exit_crop_mode(
|
||||
confirm=self.crop_temp.contains(event.pos()))
|
||||
confirm=self.crop_temp.contains(event.pos())) # 根据点击位置决定是否确认裁剪
|
||||
|
||||
def ensure_point_within_crop_bounds(self, point, handle):
|
||||
def ensure_point_within_crop_bounds(self, point, handle): # 确保点在裁剪边界内
|
||||
"""Returns the point, or the nearest point within the pixmap."""
|
||||
|
||||
if handle == self.crop_handle_topleft:
|
||||
topleft = QtCore.QPointF(0, 0)
|
||||
bottomright = self.crop_temp.bottomRight()
|
||||
if handle == self.crop_handle_bottomleft:
|
||||
topleft = QtCore.QPointF(0, self.crop_temp.top())
|
||||
bottomright = QtCore.QPointF(
|
||||
if handle == self.crop_handle_topleft: # 如果是左上角手柄
|
||||
topleft = QtCore.QPointF(0, 0) # 左上角边界
|
||||
bottomright = self.crop_temp.bottomRight() # 右下角边界(临时裁剪区域的右下角)
|
||||
if handle == self.crop_handle_bottomleft: # 如果是左下角手柄
|
||||
topleft = QtCore.QPointF(0, self.crop_temp.top()) # 左上角边界
|
||||
bottomright = QtCore.QPointF( # 右下角边界
|
||||
self.crop_temp.right(), self.pixmap().size().height())
|
||||
if handle == self.crop_handle_bottomright:
|
||||
topleft = self.crop_temp.topLeft()
|
||||
bottomright = QtCore.QPointF(
|
||||
if handle == self.crop_handle_bottomright: # 如果是右下角手柄
|
||||
topleft = self.crop_temp.topLeft() # 左上角边界(临时裁剪区域的左上角)
|
||||
bottomright = QtCore.QPointF( # 右下角边界(整个像素图的右下角)
|
||||
self.pixmap().size().width(), self.pixmap().size().height())
|
||||
if handle == self.crop_handle_topright:
|
||||
topleft = QtCore.QPointF(self.crop_temp.left(), 0)
|
||||
bottomright = QtCore.QPointF(
|
||||
if handle == self.crop_handle_topright: # 如果是右上角手柄
|
||||
topleft = QtCore.QPointF(self.crop_temp.left(), 0) # 左上角边界
|
||||
bottomright = QtCore.QPointF( # 右下角边界
|
||||
self.pixmap().size().width(), self.crop_temp.bottom())
|
||||
if handle == self.crop_edge_top:
|
||||
topleft = QtCore.QPointF(0, 0)
|
||||
bottomright = QtCore.QPointF(
|
||||
if handle == self.crop_edge_top: # 如果是顶部边缘
|
||||
topleft = QtCore.QPointF(0, 0) # 左上角边界
|
||||
bottomright = QtCore.QPointF( # 右下角边界
|
||||
self.pixmap().size().width(), self.crop_temp.bottom())
|
||||
if handle == self.crop_edge_bottom:
|
||||
topleft = QtCore.QPointF(0, self.crop_temp.top())
|
||||
bottomright = QtCore.QPointF(
|
||||
if handle == self.crop_edge_bottom: # 如果是底部边缘
|
||||
topleft = QtCore.QPointF(0, self.crop_temp.top()) # 左上角边界
|
||||
bottomright = QtCore.QPointF( # 右下角边界
|
||||
self.pixmap().size().width(), self.pixmap().size().height())
|
||||
if handle == self.crop_edge_left:
|
||||
topleft = QtCore.QPointF(0, 0)
|
||||
bottomright = QtCore.QPointF(
|
||||
if handle == self.crop_edge_left: # 如果是左侧边缘
|
||||
topleft = QtCore.QPointF(0, 0) # 左上角边界
|
||||
bottomright = QtCore.QPointF( # 右下角边界
|
||||
self.crop_temp.right(), self.pixmap().size().height())
|
||||
if handle == self.crop_edge_right:
|
||||
topleft = QtCore.QPointF(self.crop_temp.left(), 0)
|
||||
bottomright = QtCore.QPointF(
|
||||
if handle == self.crop_edge_right: # 如果是右侧边缘
|
||||
topleft = QtCore.QPointF(self.crop_temp.left(), 0) # 左上角边界
|
||||
bottomright = QtCore.QPointF( # 右下角边界
|
||||
self.pixmap().size().width(), self.pixmap().size().height())
|
||||
|
||||
point.setX(min(bottomright.x(), max(topleft.x(), point.x())))
|
||||
point.setY(min(bottomright.y(), max(topleft.y(), point.y())))
|
||||
point.setX(min(bottomright.x(), max(topleft.x(), point.x()))) # 限制点的X坐标在边界内
|
||||
point.setY(min(bottomright.y(), max(topleft.y(), point.y()))) # 限制点的Y坐标在边界内
|
||||
|
||||
return point
|
||||
return point # 返回限制后的点
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
if self.crop_mode and self.crop_mode_event_start:
|
||||
diff = event.pos() - self.crop_mode_event_start
|
||||
if self.crop_mode_move == self.crop_handle_topleft:
|
||||
new = self.ensure_point_within_crop_bounds(
|
||||
def mouseMoveEvent(self, event): # 鼠标移动事件处理
|
||||
if self.crop_mode and self.crop_mode_event_start: # 如果处于裁剪模式且有起始位置
|
||||
diff = event.pos() - self.crop_mode_event_start # 计算位置差异
|
||||
if self.crop_mode_move == self.crop_handle_topleft: # 如果移动左上角手柄
|
||||
new = self.ensure_point_within_crop_bounds( # 确保新位置在边界内
|
||||
self.crop_temp.topLeft() + diff, self.crop_mode_move)
|
||||
self.crop_temp.setTopLeft(new)
|
||||
if self.crop_mode_move == self.crop_handle_bottomleft:
|
||||
new = self.ensure_point_within_crop_bounds(
|
||||
self.crop_temp.setTopLeft(new) # 更新左上角
|
||||
if self.crop_mode_move == self.crop_handle_bottomleft: # 如果移动左下角手柄
|
||||
new = self.ensure_point_within_crop_bounds( # 确保新位置在边界内
|
||||
self.crop_temp.bottomLeft() + diff, self.crop_mode_move)
|
||||
self.crop_temp.setBottomLeft(new)
|
||||
if self.crop_mode_move == self.crop_handle_bottomright:
|
||||
new = self.ensure_point_within_crop_bounds(
|
||||
self.crop_temp.setBottomLeft(new) # 更新左下角
|
||||
if self.crop_mode_move == self.crop_handle_bottomright: # 如果移动右下角手柄
|
||||
new = self.ensure_point_within_crop_bounds( # 确保新位置在边界内
|
||||
self.crop_temp.bottomRight() + diff, self.crop_mode_move)
|
||||
self.crop_temp.setBottomRight(new)
|
||||
if self.crop_mode_move == self.crop_handle_topright:
|
||||
new = self.ensure_point_within_crop_bounds(
|
||||
self.crop_temp.setBottomRight(new) # 更新右下角
|
||||
if self.crop_mode_move == self.crop_handle_topright: # 如果移动右上角手柄
|
||||
new = self.ensure_point_within_crop_bounds( # 确保新位置在边界内
|
||||
self.crop_temp.topRight() + diff, self.crop_mode_move)
|
||||
self.crop_temp.setTopRight(new)
|
||||
if self.crop_mode_move == self.crop_edge_top:
|
||||
new = self.ensure_point_within_crop_bounds(
|
||||
self.crop_temp.setTopRight(new) # 更新右上角
|
||||
if self.crop_mode_move == self.crop_edge_top: # 如果移动顶部边缘
|
||||
new = self.ensure_point_within_crop_bounds( # 确保新位置在边界内
|
||||
self.crop_temp.topLeft() + diff, self.crop_mode_move)
|
||||
self.crop_temp.setTop(new.y())
|
||||
if self.crop_mode_move == self.crop_edge_left:
|
||||
new = self.ensure_point_within_crop_bounds(
|
||||
self.crop_temp.setTop(new.y()) # 更新顶部
|
||||
if self.crop_mode_move == self.crop_edge_left: # 如果移动左侧边缘
|
||||
new = self.ensure_point_within_crop_bounds( # 确保新位置在边界内
|
||||
self.crop_temp.topLeft() + diff, self.crop_mode_move)
|
||||
self.crop_temp.setLeft(new.x())
|
||||
if self.crop_mode_move == self.crop_edge_bottom:
|
||||
new = self.ensure_point_within_crop_bounds(
|
||||
self.crop_temp.setLeft(new.x()) # 更新左侧
|
||||
if self.crop_mode_move == self.crop_edge_bottom: # 如果移动底部边缘
|
||||
new = self.ensure_point_within_crop_bounds( # 确保新位置在边界内
|
||||
self.crop_temp.bottomLeft() + diff, self.crop_mode_move)
|
||||
self.crop_temp.setBottom(new.y())
|
||||
if self.crop_mode_move == self.crop_edge_right:
|
||||
new = self.ensure_point_within_crop_bounds(
|
||||
self.crop_temp.setBottom(new.y()) # 更新底部
|
||||
if self.crop_mode_move == self.crop_edge_right: # 如果移动右侧边缘
|
||||
new = self.ensure_point_within_crop_bounds( # 确保新位置在边界内
|
||||
self.crop_temp.topRight() + diff, self.crop_mode_move)
|
||||
self.crop_temp.setRight(new.x())
|
||||
self.update()
|
||||
self.crop_mode_event_start = event.pos()
|
||||
event.accept()
|
||||
else:
|
||||
super().mouseMoveEvent(event)
|
||||
self.crop_temp.setRight(new.x()) # 更新右侧
|
||||
self.update() # 更新项目显示
|
||||
self.crop_mode_event_start = event.pos() # 更新事件起始位置
|
||||
event.accept() # 接受事件
|
||||
else: # 非裁剪模式或没有起始位置
|
||||
super().mouseMoveEvent(event) # 调用父类处理
|
||||
|
||||
def mouseReleaseEvent(self, event):
|
||||
if self.crop_mode:
|
||||
self.crop_mode_move = None
|
||||
self.crop_mode_event_start = None
|
||||
event.accept()
|
||||
else:
|
||||
super().mouseReleaseEvent(event)
|
||||
def mouseReleaseEvent(self, event): # 鼠标释放事件处理
|
||||
if self.crop_mode: # 如果处于裁剪模式
|
||||
self.crop_mode_move = None # 清除移动类型
|
||||
self.crop_mode_event_start = None # 清除事件起始位置
|
||||
event.accept() # 接受事件
|
||||
else: # 非裁剪模式
|
||||
super().mouseReleaseEvent(event) # 调用父类处理
|
||||
|
||||
|
||||
@register_item
|
||||
class BeeTextItem(BeeItemMixin, QtWidgets.QGraphicsTextItem):
|
||||
@register_item # 使用装饰器注册该类
|
||||
class BeeTextItem(BeeItemMixin, QtWidgets.QGraphicsTextItem): # 文本项目类,继承自BeeItemMixin和QtWidgets.QGraphicsTextItem
|
||||
"""Class for text added by the user."""
|
||||
|
||||
TYPE = 'text'
|
||||
TYPE = 'text' # 项目类型标识符
|
||||
|
||||
def __init__(self, text=None, **kwargs):
|
||||
super().__init__(text or "Text")
|
||||
self.save_id = None
|
||||
logger.debug(f'Initialized {self}')
|
||||
self.is_image = False
|
||||
self.init_selectable()
|
||||
self.is_editable = True
|
||||
self.edit_mode = False
|
||||
self.setDefaultTextColor(QtGui.QColor(*COLORS['Scene:Text']))
|
||||
def __init__(self, text=None, **kwargs): # 初始化文本项目
|
||||
super().__init__(text or "Text") # 调用父类构造函数,默认文本为"Text"
|
||||
self.save_id = None # 保存ID,用于标识项目
|
||||
logger.debug(f'Initialized {self}') # 记录初始化日志
|
||||
self.is_image = False # 标记为非图像类型
|
||||
self.init_selectable() # 初始化可选择属性
|
||||
self.is_editable = True # 标记为可编辑
|
||||
self.edit_mode = False # 编辑模式标志
|
||||
self.setDefaultTextColor(QtGui.QColor(*COLORS['Scene:Text'])) # 设置默认文本颜色
|
||||
|
||||
@classmethod
|
||||
@classmethod # 类方法,从数据创建项目
|
||||
def create_from_data(cls, **kwargs):
|
||||
data = kwargs.get('data', {})
|
||||
item = cls(**data)
|
||||
return item
|
||||
data = kwargs.get('data', {}) # 获取项目数据
|
||||
item = cls(**data) # 创建项目实例
|
||||
return item # 返回创建的项目
|
||||
|
||||
def __str__(self):
|
||||
txt = self.toPlainText()[:40]
|
||||
return (f'Text "{txt}"')
|
||||
def __str__(self): # 返回项目的字符串表示
|
||||
txt = self.toPlainText()[:40] # 获取文本前40个字符
|
||||
return (f'Text "{txt}"') # 返回格式化的字符串
|
||||
|
||||
def get_extra_save_data(self):
|
||||
return {'text': self.toPlainText()}
|
||||
def get_extra_save_data(self): # 获取需要保存的额外数据
|
||||
return {'text': self.toPlainText()} # 返回文本内容
|
||||
|
||||
def contains(self, point):
|
||||
return self.boundingRect().contains(point)
|
||||
def contains(self, point): # 检查点是否在项目内
|
||||
return self.boundingRect().contains(point) # 检查点是否在边界矩形内
|
||||
|
||||
def paint(self, painter, option, widget):
|
||||
painter.setPen(Qt.PenStyle.NoPen)
|
||||
color = QtGui.QColor(0, 0, 0)
|
||||
color.setAlpha(40)
|
||||
brush = QtGui.QBrush(color)
|
||||
painter.setBrush(brush)
|
||||
painter.drawRect(QtWidgets.QGraphicsTextItem.boundingRect(self))
|
||||
option.state = QtWidgets.QStyle.StateFlag.State_Enabled
|
||||
super().paint(painter, option, widget)
|
||||
self.paint_selectable(painter, option, widget)
|
||||
def paint(self, painter, option, widget): # 绘制项目
|
||||
painter.setPen(Qt.PenStyle.NoPen) # 设置无笔
|
||||
color = QtGui.QColor(0, 0, 0) # 创建黑色
|
||||
color.setAlpha(40) # 设置透明度
|
||||
brush = QtGui.QBrush(color) # 创建画刷
|
||||
painter.setBrush(brush) # 设置画刷
|
||||
painter.drawRect(QtWidgets.QGraphicsTextItem.boundingRect(self)) # 绘制背景矩形
|
||||
option.state = QtWidgets.QStyle.StateFlag.State_Enabled # 设置选项状态为启用
|
||||
super().paint(painter, option, widget) # 调用父类绘制文本
|
||||
self.paint_selectable(painter, option, widget) # 绘制选择效果
|
||||
|
||||
def create_copy(self):
|
||||
item = BeeTextItem(self.toPlainText())
|
||||
item.setPos(self.pos())
|
||||
item.setZValue(self.zValue())
|
||||
item.setScale(self.scale())
|
||||
item.setRotation(self.rotation())
|
||||
if self.flip() == -1:
|
||||
item.do_flip()
|
||||
return item
|
||||
def create_copy(self): # 创建项目的副本
|
||||
item = BeeTextItem(self.toPlainText()) # 创建新项目,文本内容相同
|
||||
item.setPos(self.pos()) # 设置相同的位置
|
||||
item.setZValue(self.zValue()) # 设置相同的Z值
|
||||
item.setScale(self.scale()) # 设置相同的缩放比例
|
||||
item.setRotation(self.rotation()) # 设置相同的旋转角度
|
||||
if self.flip() == -1: # 如果当前是翻转状态
|
||||
item.do_flip() # 翻转新项目
|
||||
return item # 返回创建的副本
|
||||
|
||||
def enter_edit_mode(self):
|
||||
logger.debug(f'Entering edit mode on {self}')
|
||||
self.edit_mode = True
|
||||
self.old_text = self.toPlainText()
|
||||
self.setTextInteractionFlags(
|
||||
def enter_edit_mode(self): # 进入编辑模式
|
||||
logger.debug(f'Entering edit mode on {self}') # 记录进入编辑模式的日志
|
||||
self.edit_mode = True # 启用编辑模式
|
||||
self.old_text = self.toPlainText() # 保存当前文本,用于取消编辑
|
||||
self.setTextInteractionFlags( # 设置文本交互标志为编辑交互
|
||||
Qt.TextInteractionFlag.TextEditorInteraction)
|
||||
self.scene().edit_item = self
|
||||
self.scene().edit_item = self # 设置场景的当前编辑项目
|
||||
|
||||
def exit_edit_mode(self, commit=True):
|
||||
logger.debug(f'Exiting edit mode on {self}')
|
||||
self.edit_mode = False
|
||||
# reset selection:
|
||||
self.setTextCursor(QtGui.QTextCursor(self.document()))
|
||||
self.setTextInteractionFlags(Qt.TextInteractionFlag.NoTextInteraction)
|
||||
self.scene().edit_item = None
|
||||
if commit:
|
||||
self.scene().undo_stack.push(
|
||||
def exit_edit_mode(self, commit=True): # 退出编辑模式,参数commit表示是否确认修改
|
||||
logger.debug(f'Exiting edit mode on {self}') # 记录退出编辑模式的日志
|
||||
self.edit_mode = False # 禁用编辑模式
|
||||
# reset selection: 重置选择
|
||||
self.setTextCursor(QtGui.QTextCursor(self.document())) # 重置文本光标
|
||||
self.setTextInteractionFlags(Qt.TextInteractionFlag.NoTextInteraction) # 禁用文本交互
|
||||
self.scene().edit_item = None # 清除场景的当前编辑项目
|
||||
if commit: # 如果确认编辑
|
||||
self.scene().undo_stack.push( # 将文本更改添加到撤销栈
|
||||
commands.ChangeText(self, self.toPlainText(), self.old_text))
|
||||
if not self.toPlainText().strip():
|
||||
logger.debug('Removing empty text item')
|
||||
self.scene().undo_stack.push(
|
||||
if not self.toPlainText().strip(): # 如果文本为空
|
||||
logger.debug('Removing empty text item') # 记录删除空文本项目的日志
|
||||
self.scene().undo_stack.push( # 将删除操作添加到撤销栈
|
||||
commands.DeleteItems(self.scene(), [self]))
|
||||
else:
|
||||
self.setPlainText(self.old_text)
|
||||
else: # 如果取消编辑
|
||||
self.setPlainText(self.old_text) # 恢复旧文本
|
||||
|
||||
def has_selection_handles(self):
|
||||
def has_selection_handles(self): # 检查项目是否有选择手柄(编辑模式下没有选择手柄)
|
||||
return super().has_selection_handles() and not self.edit_mode
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
if (event.key() in (Qt.Key.Key_Enter, Qt.Key.Key_Return)
|
||||
def keyPressEvent(self, event): # 键盘按键事件处理
|
||||
if (event.key() in (Qt.Key.Key_Enter, Qt.Key.Key_Return) # 如果按下Enter键且没有修饰键
|
||||
and event.modifiers() == Qt.KeyboardModifier.NoModifier):
|
||||
self.exit_edit_mode()
|
||||
self.exit_edit_mode() # 退出编辑模式并确认
|
||||
event.accept()
|
||||
return
|
||||
if (event.key() == Qt.Key.Key_Escape
|
||||
if (event.key() == Qt.Key.Key_Escape # 如果按下Escape键且没有修饰键
|
||||
and event.modifiers() == Qt.KeyboardModifier.NoModifier):
|
||||
self.exit_edit_mode(commit=False)
|
||||
self.exit_edit_mode(commit=False) # 退出编辑模式并取消
|
||||
event.accept()
|
||||
return
|
||||
super().keyPressEvent(event)
|
||||
super().keyPressEvent(event) # 其他按键,调用父类处理
|
||||
|
||||
def copy_to_clipboard(self, clipboard):
|
||||
clipboard.setText(self.toPlainText())
|
||||
def copy_to_clipboard(self, clipboard): # 将项目复制到剪贴板
|
||||
clipboard.setText(self.toPlainText()) # 设置剪贴板内容为文本
|
||||
|
||||
|
||||
@register_item
|
||||
class BeeErrorItem(BeeItemMixin, QtWidgets.QGraphicsTextItem):
|
||||
@register_item # 使用装饰器注册该类
|
||||
class BeeErrorItem(BeeItemMixin, QtWidgets.QGraphicsTextItem): # 错误项目类,继承自BeeItemMixin和QtWidgets.QGraphicsTextItem
|
||||
"""Class for displaying error messages when an item can't be loaded
|
||||
from a bee file.
|
||||
|
||||
|
|
@ -742,65 +742,65 @@ class BeeErrorItem(BeeItemMixin, QtWidgets.QGraphicsTextItem):
|
|||
is saved.
|
||||
"""
|
||||
|
||||
TYPE = 'error'
|
||||
TYPE = 'error' # 项目类型标识符
|
||||
|
||||
def __init__(self, text=None, **kwargs):
|
||||
super().__init__(text or "Text")
|
||||
self.original_save_id = None
|
||||
logger.debug(f'Initialized {self}')
|
||||
self.is_image = False
|
||||
self.init_selectable()
|
||||
self.is_editable = False
|
||||
self.setDefaultTextColor(QtGui.QColor(*COLORS['Scene:Text']))
|
||||
def __init__(self, text=None, **kwargs): # 初始化错误项目
|
||||
super().__init__(text or "Text") # 调用父类构造函数
|
||||
self.original_save_id = None # 原始项目的保存ID
|
||||
logger.debug(f'Initialized {self}') # 记录初始化日志
|
||||
self.is_image = False # 标记为非图像类型
|
||||
self.init_selectable() # 初始化可选择属性
|
||||
self.is_editable = False # 标记为不可编辑
|
||||
self.setDefaultTextColor(QtGui.QColor(*COLORS['Scene:Text'])) # 设置默认文本颜色
|
||||
|
||||
@classmethod
|
||||
@classmethod # 类方法,从数据创建项目
|
||||
def create_from_data(cls, **kwargs):
|
||||
data = kwargs.get('data', {})
|
||||
item = cls(**data)
|
||||
return item
|
||||
data = kwargs.get('data', {}) # 获取项目数据
|
||||
item = cls(**data) # 创建项目实例
|
||||
return item # 返回创建的项目
|
||||
|
||||
def __str__(self):
|
||||
txt = self.toPlainText()[:40]
|
||||
return (f'Error "{txt}"')
|
||||
def __str__(self): # 返回项目的字符串表示
|
||||
txt = self.toPlainText()[:40] # 获取文本前40个字符
|
||||
return (f'Error "{txt}"') # 返回格式化的字符串
|
||||
|
||||
def contains(self, point):
|
||||
return self.boundingRect().contains(point)
|
||||
def contains(self, point): # 检查点是否在项目内
|
||||
return self.boundingRect().contains(point) # 检查点是否在边界矩形内
|
||||
|
||||
def paint(self, painter, option, widget):
|
||||
painter.setPen(Qt.PenStyle.NoPen)
|
||||
color = QtGui.QColor(200, 0, 0)
|
||||
brush = QtGui.QBrush(color)
|
||||
painter.setBrush(brush)
|
||||
painter.drawRect(QtWidgets.QGraphicsTextItem.boundingRect(self))
|
||||
option.state = QtWidgets.QStyle.StateFlag.State_Enabled
|
||||
super().paint(painter, option, widget)
|
||||
self.paint_selectable(painter, option, widget)
|
||||
def paint(self, painter, option, widget): # 绘制项目
|
||||
painter.setPen(Qt.PenStyle.NoPen) # 设置无笔
|
||||
color = QtGui.QColor(200, 0, 0) # 创建红色
|
||||
brush = QtGui.QBrush(color) # 创建画刷
|
||||
painter.setBrush(brush) # 设置画刷
|
||||
painter.drawRect(QtWidgets.QGraphicsTextItem.boundingRect(self)) # 绘制红色背景矩形
|
||||
option.state = QtWidgets.QStyle.StateFlag.State_Enabled # 设置选项状态为启用
|
||||
super().paint(painter, option, widget) # 调用父类绘制文本
|
||||
self.paint_selectable(painter, option, widget) # 绘制选择效果
|
||||
|
||||
def update_from_data(self, **kwargs):
|
||||
self.original_save_id = kwargs.get('save_id', self.original_save_id)
|
||||
self.setPos(kwargs.get('x', self.pos().x()),
|
||||
kwargs.get('y', self.pos().y()))
|
||||
self.setZValue(kwargs.get('z', self.zValue()))
|
||||
self.setScale(kwargs.get('scale', self.scale()))
|
||||
self.setRotation(kwargs.get('rotation', self.rotation()))
|
||||
def update_from_data(self, **kwargs): # 从数据更新项目属性
|
||||
self.original_save_id = kwargs.get('save_id', self.original_save_id) # 更新原始保存ID
|
||||
self.setPos(kwargs.get('x', self.pos().x()), # 更新X坐标
|
||||
kwargs.get('y', self.pos().y())) # 更新Y坐标
|
||||
self.setZValue(kwargs.get('z', self.zValue())) # 更新Z值
|
||||
self.setScale(kwargs.get('scale', self.scale())) # 更新缩放比例
|
||||
self.setRotation(kwargs.get('rotation', self.rotation())) # 更新旋转角度
|
||||
|
||||
def create_copy(self):
|
||||
item = BeeErrorItem(self.toPlainText())
|
||||
item.setPos(self.pos())
|
||||
item.setZValue(self.zValue())
|
||||
item.setScale(self.scale())
|
||||
item.setRotation(self.rotation())
|
||||
return item
|
||||
def create_copy(self): # 创建项目的副本
|
||||
item = BeeErrorItem(self.toPlainText()) # 创建新项目,文本内容相同
|
||||
item.setPos(self.pos()) # 设置相同的位置
|
||||
item.setZValue(self.zValue()) # 设置相同的Z值
|
||||
item.setScale(self.scale()) # 设置相同的缩放比例
|
||||
item.setRotation(self.rotation()) # 设置相同的旋转角度
|
||||
return item # 返回创建的副本
|
||||
|
||||
def flip(self, *args, **kwargs):
|
||||
def flip(self, *args, **kwargs): # 返回翻转值(错误项目永远不翻转)
|
||||
"""Returns the flip value (1 or -1)"""
|
||||
# Never display error messages flipped
|
||||
return 1
|
||||
|
||||
def do_flip(self, *args, **kwargs):
|
||||
def do_flip(self, *args, **kwargs): # 翻转项目(错误项目永远不翻转)
|
||||
"""Flips the item."""
|
||||
# Never flip error messages
|
||||
pass
|
||||
|
||||
def copy_to_clipboard(self, clipboard):
|
||||
clipboard.setText(self.toPlainText())
|
||||
def copy_to_clipboard(self, clipboard): # 将项目复制到剪贴板
|
||||
clipboard.setText(self.toPlainText()) # 设置剪贴板内容为文本
|
||||
Loading…
Reference in a new issue