废话不多说,直接开门见山。
QWidgetList
类本身有一个contextMenuEvent
函数,直接继承类过后重新定义(多态)这个函数,把菜单相关选项放进去就可以了。
现在我们遇到的问题是:如果使用Qt Designer
直接绘制出主窗口mian_window
,之后在其中绘制QWidgetList
控件的话,那么我们在逻辑代码中似乎就无法直接定义contextMenuEvent
函数了。因为QWidgetList
已经先由Qt Designer
生成的UI代码先一步实例化了,我们也可以在UI代码里面修改让QWidgetList
在实例化的时候使用我们自己定义的继承类,但是总归是太麻烦,经过查阅资料以后,查到一个解决办法:
参考资料:How do I make a context menu for each item in a QListWidget?
直接上代码吧:(因为我这个是工程代码,不是范例,所以不能直接运行,仅能提供思路参考)
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
class Main_Window(QMainWindow, Ui_MainWindow):
def __init__(self, conf: Config, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setupUi(self)
self.usergamelistWidget.installEventFilter(self)
self.R_Menu()
def R_Menu(self):
self.r_menu = QMenu()
# 设置右键菜单项目,链接信号函数
edit = QAction("编辑", self)
edit.triggered.connect(self.Edit_GameData)
open_floder = QAction("打开游戏文件夹", self)
open_floder.triggered.connect(self.Open_Game_Folder)
open_save = QAction("打开存档文件夹", self)
open_save.triggered.connect(self.Open_Save_Folder)
del_game = QAction("删除同步链接", self)
del_game.triggered.connect(self.Del_GameData)
# 添加菜单子项
self.r_menu.addAction(edit)
self.r_menu.addAction(open_floder)
self.r_menu.addAction(open_save)
self.r_menu.addAction(del_game)
#关键函数,重新定义(多态)eventFilter方法
def eventFilter(self, watched: QObject, event: QEvent) -> bool:
if event.type() == QEvent.ContextMenu and watched is self.usergamelistWidget:
#self.usergamelistWidget是QWidgetList的一个实例
item = watched.itemAt(event.pos())
if item is None:
print("no select")
else:
self.r_menu.exec(event.globalPos())
return True
return super().eventFilter(watched, event)
def Edit_GameData(self):
#该函数返回QWidgetList中被选中的QWidgetListItem的list,即使只选择了
#一个QWidgetListItem也会返回一个列表
selcet_item = self.usergamelistWidget.selectedItems()[0]
#该函数返回一个QWidgetListItem在QWidgetList中的索引位置
item_index = self.usergamelistWidget.row(selcet_item)
#将参数传出去可以实现更多的功能
self.addwindow = Addgame_Window(config, item_index, self)
self.addwindow.exec()
def Del_GameData(self):
print("Del game savedata sync")
pass
def Open_Game_Folder(self):
print("open game folder")
pass
def Open_Save_Folder(self):
print("open game savedata folder")
pass