每个任务项都包含操作列表我使用 QlistWidgetItem[] 来保存它 如果我单击任务项。操作视图区域可以从taskitem.data()重新加载数据。 当任务中的每个项目都没有操作数据时,当您切换任务项目时,程序不会崩溃。 当只有一个带有操作数据的任务项时不会崩溃 但是当您切换具有操作数据的任务项时,程序会崩溃。
# This Python file uses the following encoding: utf-8
import sys
import copy
from PySide6.QtCore import Signal, Slot, QRect, Qt, QPoint
from PySide6.QtGui import QPalette, QColor, QMouseEvent, QPen, QPainter
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QListWidgetItem
# Important:
# You need to run the following command to generate the ui_form.py file
# pyside6-uic form.ui -o ui_form.py, or
# pyside2-uic form.ui -o ui_form.py
from ui_form import Ui_MainWindow
from datamanager import ActionData
from newtaskdialog import NewTaskDialog
from newmouseactiondialog import NewMouseActionDialog
class Rect:
def __init__(self, rect: QRect):
self._rect = rect
self._is_hover = False
self._is_drag = False
self._is_edge_drag = False
class RenderArea(QWidget):
signal_move_event = Signal(QMouseEvent)
signal_release_event = Signal()
def __init__(self, parent=None):
super().__init__(parent)
self.setMouseTracking(True)
self._mouse_x = 0
self._mouse_y = 0
self._previous_mouse_pos = None
# 初始绘图相关
self.pen = QPen(Qt.blue, 3)
self.rect_list = []
def isRectIncludeMouse(self, mouse_pos: QPoint, rect: QRect):
cursor_x = mouse_pos.x()
cursor_y = mouse_pos.y()
edge_weight = 8
if(cursor_x >= rect.x()
and cursor_x <= rect.x() + rect.width() - edge_weight
and cursor_y >= rect.y()
and cursor_y <= rect.y() + rect.height() - edge_weight
):
return True
else:
return False
def isMouseOnRectEdge(self, mouse_pos: QPoint, rect: QRect):
cursor_x = mouse_pos.x()
cursor_y = mouse_pos.y()
edge_weight = 8
if(cursor_x <= rect.x() + rect.width()
and cursor_x > rect.x() + rect.width() - edge_weight
and cursor_y <= rect.y() + rect.height()
and cursor_y > rect.y() + rect.height() - edge_weight
):
return True
else:
return False
def mousePressEvent(self, event: QMouseEvent):
self._previous_mouse_pos = event.position().toPoint()
is_there_one_drag = False
is_there_one_edge_drag = False
for rect_index in range(len(self.rect_list)):
if (self.isRectIncludeMouse(event.position().toPoint(), self.rect_list[rect_index]._rect)
and not is_there_one_drag):
self.rect_list[rect_index]._is_drag = True
is_there_one_drag = True
elif(self.isMouseOnRectEdge(event.position().toPoint(), self.rect_list[rect_index]._rect)
and not is_there_one_edge_drag):
self.rect_list[rect_index]._is_edge_drag = True
is_there_one_edge_drag = True
def mouseReleaseEvent(self, event: QMouseEvent):
for rect_index in range(len(self.rect_list)):
self.rect_list[rect_index]._is_drag = False
self.rect_list[rect_index]._is_edge_drag = False
self.signal_release_event.emit()
def mouseMoveEvent(self, event: QMouseEvent):
for rect_index in range(len(self.rect_list)):
if self.rect_list[rect_index]._is_drag:
new_rect_x = (event.position().x() - self._previous_mouse_pos.x()) + self.rect_list[rect_index]._rect.x()
new_rect_y = (event.position().y() - self._previous_mouse_pos.y()) + self.rect_list[rect_index]._rect.y()
if new_rect_x >= 0 and new_rect_x <= self.width():
self.rect_list[rect_index]._rect.moveTo(new_rect_x, self.rect_list[rect_index]._rect.y())
if new_rect_y >= 0 and new_rect_y <= self.height():
self.rect_list[rect_index]._rect.moveTo(self.rect_list[rect_index]._rect.x(), new_rect_y)
self._previous_mouse_pos = event.position().toPoint()
elif self.rect_list[rect_index]._is_edge_drag:
new_rect_widght = (event.position().x() - self._previous_mouse_pos.x()) + self.rect_list[rect_index]._rect.width()
new_rect_height = (event.position().y() - self._previous_mouse_pos.y()) + self.rect_list[rect_index]._rect.height()
if new_rect_widght < 16:
new_rect_widght = 16
if new_rect_height < 16:
new_rect_height = 16
self.rect_list[rect_index]._rect.setWidth(new_rect_widght)
self.rect_list[rect_index]._rect.setHeight(new_rect_height)
self._previous_mouse_pos = event.position().toPoint()
self.update()
self.signal_move_event.emit(event)
QWidget.mouseMoveEvent(self, event)
def paintEvent(self, event):
# 绘制一个矩形
with QPainter(self) as painter:
painter.setPen(self.pen)
for rect in self.rect_list:
if rect._is_hover:
painter.save()
pen = QPen(Qt.red, 3)
painter.setPen(pen)
painter.drawRect(rect._rect)
painter.restore()
else:
painter.drawRect(rect._rect)
# 碰撞检查
# 拖动
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# new action type dick
self.action_type_dict = {
"启动游戏": 0,
"释放游戏": 1,
"鼠标": 2,
"键盘": 3,
}
# self.setMouseTracking(True)
self._NewTaskDialog = NewTaskDialog()
self._NewTaskDialog.hide()
self._new_mouse_action_dialog = NewMouseActionDialog()
self._new_mouse_action_dialog.hide()
# 绘制区域初始化
self._render_area = RenderArea()
# 设置背景颜色
back_ground_palette = QPalette()
back_ground_palette.setColor(QPalette.Window, QColor(200, 200, 200))
self._render_area.setPalette(back_ground_palette)
self._render_area.setAutoFillBackground(True)
# 设置布局,加入父窗口
right_widget_layout = QHBoxLayout()
right_widget_layout.addWidget(self._render_area)
self.ui.widget_right.setLayout(right_widget_layout)
# 新建 Task slot
self.ui.pushButtonNewTask.clicked.connect(self.OpenNewTaskDialog)
# 编辑 Task
self.ui.listWidgetTaskList.itemDoubleClicked.connect(self.OpenEditTaskDialog)
self.ui.listWidgetTaskList.itemClicked.connect(self.TaskItemSelected)
# delete Task
self.ui.pushButtonDeleteTask.clicked.connect(self.DeleteTask)
# 添加或修改 Task slot
self._NewTaskDialog.signal_add_clicked.connect(self.AddNewTask)
self._NewTaskDialog.signal_edit_clicked.connect(self.EditTask)
# Move up or Move Down Task slot
self.ui.pushButtonTaskMoveUp.clicked.connect(self.TaskMoveUp)
self.ui.pushButtonTaskMoveDown.clicked.connect(self.TaskMoveDown)
# new action slot
self.ui.pushButtonNewAction.clicked.connect(self.OpenNewActionDialog)
self.ui.listWidgetActionList.itemDoubleClicked.connect(self.OpenEditActionDialog)
self.ui.pushButtonDeleteAction.clicked.connect(self.DeleteAction)
self.ui.listWidgetActionList.itemClicked.connect(self.ActionItemSelected)
# new mouse action slot
self._new_mouse_action_dialog.signal_add_confirm_clicked.connect(self.AddMouseAction)
self._new_mouse_action_dialog.signal_edit_confirm_clicked.connect(self.EditMouseAction)
# Move up and Move down action slot
self.ui.pushButtonActionMoveUp.clicked.connect(self.ActionMoveUp)
self.ui.pushButtonActionMoveDown.clicked.connect(self.ActionMoveDown)
#update mouse position
self._render_area.signal_move_event.connect(self.UpdateStatus)
self._render_area.signal_release_event.connect(self.SaveRect)
@Slot()
def OpenNewTaskDialog(self):
self._NewTaskDialog.OpenNewDialog()
@Slot()
def OpenEditTaskDialog(self):
self._NewTaskDialog.OpenEditDialog(self.ui.listWidgetTaskList.currentItem().text())
@Slot()
def TaskItemSelected(self):
current_item = self.ui.listWidgetTaskList.currentItem()
action_data_list = current_item.data(Qt.UserRole)
for i in range(self.ui.listWidgetActionList.count()):
self.ui.listWidgetActionList.takeItem(0)
for action_data in action_data_list:
self.ui.listWidgetActionList.addItem(action_data)
@Slot()
def DeleteTask(self):
current_row = self.ui.listWidgetTaskList.currentRow()
if self.ui.listWidgetTaskList.count() > 0 and current_row >= 0:
self.ui.listWidgetTaskList.takeItem(current_row)
@Slot()
def AddNewTask(self, name: str):
item = QListWidgetItem()
item.setText(name)
action_data_list: List[QListWidgetItem] = []
item.setData(Qt.UserRole, action_data_list)
self.ui.listWidgetTaskList.addItem(item)
@Slot()
def EditTask(self, name: str):
currenttask = self.ui.listWidgetTaskList.currentItem()
currenttask.setText(name)
self.ui.listWidgetTaskList.setCurrentItem(currenttask)
@Slot()
def TaskMoveUp(self):
current_row = self.ui.listWidgetTaskList.currentRow()
if current_row > 0 and self.ui.listWidgetTaskList.count() > 0:
above_item = self.ui.listWidgetTaskList.takeItem(current_row - 1)
self.ui.listWidgetTaskList.insertItem(current_row, above_item)
@Slot()
def TaskMoveDown(self):
current_row = self.ui.listWidgetTaskList.currentRow()
if current_row < self.ui.listWidgetTaskList.count() - 1 and self.ui.listWidgetTaskList.count() > 0:
below_item = self.ui.listWidgetTaskList.takeItem(current_row + 1)
self.ui.listWidgetTaskList.insertItem(current_row, below_item)
@Slot()
def OpenNewActionDialog(self):
current_action_type = self.action_type_dict[self.ui.comboBoxActionType.currentText()]
if current_action_type == self.action_type_dict["启动游戏"]:
pass
elif current_action_type == self.action_type_dict["释放游戏"]:
pass
elif current_action_type == self.action_type_dict["鼠标"]:
self._new_mouse_action_dialog.OpenNewDialog()
@Slot()
def OpenEditActionDialog(self):
currentItem = self.ui.listWidgetActionList.currentItem()
action_data = currentItem.data(Qt.UserRole)
if action_data._action_type == self.action_type_dict["鼠标"]:
self._new_mouse_action_dialog.OpenEditDialog(action_data._mouse_action_data._mouse_action_type, action_data._mouse_action_data._timer)
@Slot()
def DeleteAction(self):
current_row = self.ui.listWidgetActionList.currentRow()
if self.ui.listWidgetActionList.count() > 0 and current_row >= 0:
self.ui.listWidgetActionList.takeItem(current_row)
self._render_area.rect_list.clear()
self._render_area.update()
@Slot()
def ActionItemSelected(self):
currentItem = self.ui.listWidgetActionList.currentItem()
mouse_action_data = currentItem.data(Qt.UserRole)._mouse_action_data
rect = Rect(QRect(mouse_action_data._x, mouse_action_data._y, mouse_action_data._width, mouse_action_data._height))
self._render_area.rect_list.clear()
self._render_area.rect_list.append(rect)
self._render_area.update()
@Slot()
def AddMouseAction(self, mouseactiondata):
action_data = ActionData()
action_data._action_type = self.action_type_dict["鼠标"]
action_data._mouse_action_data = mouseactiondata
item = QListWidgetItem()
item.setText(mouseactiondata._mouse_action_name)
item.setData(Qt.UserRole, action_data)
self.ui.listWidgetActionList.addItem(item)
#save
self.SaveActionList()
@Slot()
def EditMouseAction(self, mouseactiondata):
currentItem = self.ui.listWidgetActionList.currentItem()
action_data = currentItem.data(Qt.UserRole)
action_data._mouse_action_data._mouse_action_type = mouseactiondata._mouse_action_type
action_data._mouse_action_data._mouse_action_name = mouseactiondata._mouse_action_name
action_data._mouse_action_data._timer = mouseactiondata._timer
currentItem.setData(Qt.UserRole, action_data)
currentItem.setText(action_data._mouse_action_data._mouse_action_name)
self.ui.listWidgetActionList.setCurrentItem(currentItem)
@Slot()
def ActionMoveUp(self):
current_row = self.ui.listWidgetActionList.currentRow()
if current_row > 0 and self.ui.listWidgetActionList.count() > 0:
above_item = self.ui.listWidgetActionList.takeItem(current_row - 1)
self.ui.listWidgetActionList.insertItem(current_row, above_item)
@Slot()
def ActionMoveDown(self):
current_row = self.ui.listWidgetActionList.currentRow()
if current_row < self.ui.listWidgetActionList.count() - 1 and self.ui.listWidgetActionList.count() > 0:
below_item = self.ui.listWidgetActionList.takeItem(current_row + 1)
self.ui.listWidgetActionList.insertItem(current_row, below_item)
@Slot()
def UpdateStatus(self, event: QMouseEvent):
pos_x = int(event.position().x())
pos_y = int(event.position().y())
str_pos = f"X:{pos_x} Y:{pos_y}"
self.ui.statusbar.showMessage(str_pos)
# print(f"X:{pos_x}, Y:{pos_y}")
def SaveActionList(self):
action_data_list = []
for row in range(self.ui.listWidgetActionList.count()):
item = self.ui.listWidgetActionList.item(row)
action_data_list.append(item)
currenttask = self.ui.listWidgetTaskList.currentItem()
currenttask.setData(Qt.UserRole, action_data_list)
self.ui.listWidgetTaskList.setCurrentItem(currenttask)
不知道如何解决
您在选择项目时似乎遇到了此错误。当您选择可以使用的物品时捕捉
if currentItem:
....
这样您就可以确定该项目是否可用(或存在)。在您的
ActionItemSelected
函数中检查这一点。另外,qt 拥有您使用的大部分插槽。你正在为自己创造不必要的工作