gpt4 book ai didi

python - 在多个 QTableView 上创建不同的上下文菜单

转载 作者:行者123 更新时间:2023-12-02 02:56:50 25 4
gpt4 key购买 nike

我在 QMainWindow 中有两个 QTableView,我想在其中一个上创建一个上下文菜单,然后在另一个上创建另一个上下文菜单。

到目前为止,创建上下文菜单并定义操作是有效的。但上下文菜单会在整个应用程序内的任何地方弹出。我不知道如何将其限制为只有一张特定的表。我认为这与 contextMenuEvent() 有关,它是 QMainWindow 的成员,但我不知道如何更改这部分。尝试创建继承 QTableView 的自定义类没有成功,因为我不确定从哪里开始。

这是我尝试过的:

populate_table_1()populate_table_2() 方法仅用于将一些数据填充到表中。 get_selected_item_TV1() 方法从 table_1 的一行中获取必要的数据。 delete_file() 方法是我在从 contextMenuEvent() 方法调用删除操作时想要执行的操作的示例。到目前为止,此代码有效,但我希望仅当我右键单击 table_1 的一行时才弹出上下文菜单,并且在右键单击其他地方时根本不显示该菜单。

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *



data_1 = ["file_name", "file_infos"]
data_2 = ["other_stuff_1", "other_stuff_2"]


class Ui_MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()

def initUI(self):
self.setWindowTitle("MyApp")
self.resize(450, 280)
centralwidget = QWidget(self)

#]===================================================================[#

# table_1
table_1 = QTableView(
centralwidget,
selectionBehavior=QAbstractItemView.SelectRows,
editTriggers=QAbstractItemView.NoEditTriggers
)
# table_1 models
self.modelTV1 = QStandardItemModel(0, 2, centralwidget)
self.modelTV1.setHorizontalHeaderLabels(["column 1", "column 2"])
table_1.setModel(self.modelTV1)

self.selectionModelTV1 = table_1.selectionModel()

#]===================================================================[#

# table_2
table_2 = QTableView(
centralwidget,
selectionBehavior=QAbstractItemView.SelectRows,
editTriggers=QAbstractItemView.NoEditTriggers,
)
# table_2 models
self.modelTV2 = QStandardItemModel(0, 2, centralwidget)
self.modelTV2.setHorizontalHeaderLabels(["column 1", "column 2"])
table_2.setModel(self.modelTV2)

self.selectionModelTV2 = table_2.selectionModel()

v_Layout1 = QVBoxLayout()
v_Layout1.addWidget(table_1)
v_Layout1.addWidget(table_2)
gridLayout = QGridLayout(centralwidget)
gridLayout.addLayout(v_Layout1, 0, 0, 1, 1)
self.setCentralWidget(centralwidget)


def populate_table_1(self):
self.modelTV1.setRowCount(0)
for item in data_1:
self.modelTV1.insertRow(0)
for i, text in enumerate(data_1):
self.modelTV1.setItem(0, i, QStandardItem(text))


def populate_table_2(self):
self.modelTV2.setRowCount(0)
for item in data_2:
self.modelTV2.insertRow(0)
for i, text in enumerate(data_2):
self.modelTV2.setItem(0, i, QStandardItem(text))


def contextMenuEvent(self, event):
self.contextMenu = QMenu(self)
deleteAction = QAction("Delete", self)

self.contextMenu.addAction(deleteAction)
deleteAction.triggered.connect(lambda: self.delete_file(event))

self.contextMenu.popup(QCursor.pos())


def get_selected_item_TV1(self):
# get the row's text from the first column in table_1
listed_items = self.selectionModelTV1.selectedRows()
for index in listed_items:
selected_item = index.data()
return f"table_1 - row_{index.row()} - {selected_item}"


def delete_file(self, event):
item = self.get_selected_item_TV1()
print(f"Deleting: {item}")



if __name__ == "__main__":
import sys

app = QApplication(sys.argv)
mainUI = Ui_MainWindow()

mainUI.populate_table_1()
mainUI.populate_table_2()
mainUI.show()

sys.exit(app.exec_())

最佳答案

有很多替代方案:

  • 检测鼠标按下时是否处于某个区域,例如第一个QTableView。在这种情况下,小部件必须可以在 contextMenuEvent() 中访问,因此您必须将 table_1 更改为 self.table_1,然后使用 underMouse():

    def contextMenuEvent(self, event):
    if self.table_1.underMouse():
    self.contextMenu = QMenu(self)
    deleteAction = QAction("Delete", self)

    self.contextMenu.addAction(deleteAction)
    deleteAction.triggered.connect(lambda: self.delete_file(event))

    self.contextMenu.popup(QCursor.pos())
  • 为每个QTableView实现contextMenuEvent方法:

    class TableView(QTableView):
    def contextMenuEvent(self, event):
    self.contextMenu = QMenu(self)
    deleteAction = QAction("Delete", self)

    self.contextMenu.addAction(deleteAction)
    deleteAction.triggered.connect(lambda: self.delete_file(event))

    self.contextMenu.popup(QCursor.pos())

    def get_selected_item_TV1(self):
    # get the row's text from the first column in table_1
    listed_items = self.selectionModel().selectedRows()
    for index in listed_items:
    selected_item = index.data()
    return f"table_1 - row_{index.row()} - {selected_item}"

    def delete_file(self, event):
    item = self.get_selected_item_TV1()
    print(f"Deleting: {item}")

    然后您必须将 table_1 = QTableView(... 更改为 table_1 = TableView(...

  • 另一种选择是使用 customContextMenuRequested 信号,为此您必须启用 Qt::CustomContextMenu 标志:

    table_1 = QTableView(
    centralwidget,
    selectionBehavior=QAbstractItemView.SelectRows,
    editTriggers=QAbstractItemView.NoEditTriggers,
    contextMenuPolicy=Qt.CustomContextMenu
    )
    table_1.customContextMenuRequested.connect(self.on_customContextMenuRequested)
    def on_customContextMenuRequested(self):
    self.contextMenu = QMenu(self)
    deleteAction = QAction("Delete", self)

    self.contextMenu.addAction(deleteAction)
    deleteAction.triggered.connect(lambda: self.delete_file())

    self.contextMenu.popup(QCursor.pos())

    def delete_file(self):
    item = self.get_selected_item_TV1()
    print(f"Deleting: {item}")

关于python - 在多个 QTableView 上创建不同的上下文菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60922666/

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