gpt4 book ai didi

python - 我可以使用 eventFilter 来忽略小部件的事件吗

转载 作者:行者123 更新时间:2023-12-01 08:25:14 26 4
gpt4 key购买 nike

我可以设置我的eventFilter来忽略小部件的“默认”事件,例如。 mousePressEvents 等?或者这两者可以混合在一起吗?

在我的代码中,我有一个 mousePressEvent 和一个为 QMenu 中的菜单项的右键单击菜单创建的自定义事件。

有时,当我执行代码/或在选项卡上单击鼠标右键时,我会看到:

AttributeError: 'PySide2.QtCore.QEvent' object has no attribute 'pos'

或者有时:

RuntimeWarning: Invalid return value in function QTabBar.eventFilter, expected bool, got NoneType.

因此,是否有更好的方法来解决它,或者我应该重新考虑如何继续进行重命名项目删除项目,如中所示show_adv_qmenu()

class MyWin(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MyWin, self).__init__()

self.rename_menu_allowed = False

central_widget = QtGui.QWidget()
self.setCentralWidget(central_widget)
vlay = QtGui.QVBoxLayout(central_widget)
hlay = QtGui.QHBoxLayout()
vlay.addLayout(hlay)
vlay.addStretch()

self.add_button = QtGui.QToolButton()
self.tab_bar = QtGui.QTabBar(self)
self.add_button.setIcon(QtGui.QIcon('add.png'))
self.add_button.setMenu(self.set_menu())
self.add_button.setPopupMode(QtGui.QToolButton.InstantPopup)

self.tab_bar.setTabButton(
0,
QtGui.QTabBar.ButtonPosition.RightSide,
self.add_button
)

hlay.addWidget(self.add_button)
hlay.addWidget(self.tab_bar)

self.my_extra_menus = defaultdict(list)

def set_menu(self):
menu_options = ['food', 'drinks', 'snacks']
qmenu = QtGui.QMenu(self.add_button)
for opt in menu_options:
qmenu.addAction(opt, partial(self.set_new_tab, opt))
return qmenu

def set_new_tab(self, opt):
self.tab_bar.addTab(opt)

def mousePressEvent(self, event):
index = self.tab_bar.tabAt(event.pos())

if event.button() == QtCore.Qt.RightButton:
self._showContextMenu(event.pos(), index)

else:
super(MyWin, self).mousePressEvent(event)


def eventFilter(self, obj, event):
# Custom event only for right mouse click within the qmenu

if obj == self.qmenu:
if event.type() == QtCore.QEvent.MouseButtonPress and event.button() == QtCore.Qt.RightButton:
index = self.tab_bar.tabAt(event.pos())
action = obj.actionAt(event.pos())
self.show_adv_qmenu(obj, action, index)

def _showContextMenu(self, position, index):
self.qmenu = QtGui.QMenu(self)
self.qmenu.setTearOffEnabled(True) # New item is not shown in tearoff mode
self.qmenu.setTitle(self.tab_bar.tabText(index))

self.qmenu.installEventFilter(self)

add_item_action = QtGui.QAction('Add Menu Item', self)
slot = partial(self._addMenuItem, index)
add_item_action.triggered.connect(slot)
self.qmenu.addAction(add_item_action)
self.qmenu.addSeparator()

if self.my_extra_menus.get(index):
for menuItem in self.my_extra_menus[index]:
self.qmenu.addMenu(menuItem)

self.qmenu.addSeparator()

global_position = self.mapToGlobal(self.pos())
self.qmenu.exec_(QtCore.QPoint(
global_position.x() - self.pos().x() + position.x(),
global_position.y() - self.pos().y() + position.y()
))

def _addMenuItem(self, index):
# For first tier menu
first_tier_menu = []
for i in self.qmenu.actions():
first_tier_menu.append(i.text())

new_menu_name, ok = QtGui.QInputDialog.getText(
self,
"Name of Menu",
"Name of new Menu Item:"
)

if ok:
if new_menu_name in list(filter(None, first_tier_menu)):
self.err_popup()
else:
menu = QtGui.QMenu(new_menu_name, self)
menu.setTearOffEnabled(True) # New item is shown in tearoff mode, unless I close and re-tearoff
add_item_action = QtGui.QAction('Add sub Item', menu)
slot = partial(self._addActionItem, menu)
add_item_action.triggered.connect(slot)
menu.addAction(add_item_action)
menu.addSeparator()

self.my_extra_menus[index].append(menu)

def _addActionItem(self, menu):
# For second tier menu
new_item_name, ok = QtGui.QInputDialog.getText(
self,
"Name of Menu Item",
"Name of new Menu Item:"
)

second_tier_menu = []
for i in menu.actions():
second_tier_menu.append(i.text())

if ok:
if new_item_name in list(filter(None, second_tier_menu)):
self.err_popup()
else:
action = QtGui.QAction(new_item_name, self)
slot = partial(self._callActionItem, new_item_name)
action.setCheckable(True)
action.toggled.connect(slot)
menu.addAction(action)


def _callActionItem(self, name, flag):
# Function for the checked items..
print name
print flag

def show_adv_qmenu(self, obj, action, index):
self.adv_qmenu = QtGui.QMenu()

rename_menu_action = QtGui.QAction('Rename Item', self)
rename_slot = partial(self.rename_menu_item, obj, action)
rename_menu_action.triggered.connect(rename_slot)
self.adv_qmenu.addAction(rename_menu_action)

delete_menu_action = QtGui.QAction('Delete Item', self)
delete_slot = partial(self.delete_menu_item, obj, action, index)
delete_menu_action.triggered.connect(delete_slot)
self.adv_qmenu.addAction(delete_menu_action)

# global_position = self.mapToGlobal(self.pos())
# self.adv_qmenu.exec_(QtCore.QPoint(global_position))

self.adv_qmenu.exec_(QtGui.QCursor().pos())


def rename_menu_item(self, obj, selected_action):
rename_name, ok = QtGui.QInputDialog.getText(
self,
"renaming",
"New name:"
)

if ok:
for i in obj.actions():
if selected_action.text() == i.text():
i.setText(rename_name)
print "Name changed : {0} --> {1}".format(selected_action.text(), i.text())


def delete_menu_item(self, obj, selected_action, index):
obj.removeAction(selected_action)



def err_popup(self):
msg = QtGui.QMessageBox()
msg.setIcon(QtGui.QMessageBox.Critical)
msg.setText("Input name already exists. Please check.")
msg.setWindowTitle('Unable to add item')
msg.setStandardButtons(QtGui.QMessageBox.Ok)
msg.exec_()

抱歉代码太长..

最佳答案

eventFilter 必须返回一个 bool 值,但在您的情况下它不会返回任何内容,因此第二个错误会抛出您。我还改进了你的逻辑:

def eventFilter(self, obj, event):
# Custom event only for right mouse click within the qmenu
if obj is self.qmenu and event.type() == QtCore.QEvent.MouseButtonPress:
if event.button() == QtCore.Qt.RightButton:
index = self.tab_bar.tabAt(event.pos())
action = self.qmenu.actionAt(event.pos())
if index != -1 and action is not None:
self.show_adv_qmenu(obj, action, index)
return super(MyWin, self).eventFilter(obj, event)

关于python - 我可以使用 eventFilter 来忽略小部件的事件吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54300158/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com