关键词:
【中文标题】PyQt5 QTableWidget:右键选择列,并在上下文菜单中显示删除条目【英文标题】:PyQt5 QTableWidget: select column with right click, and show a delete entry in context menu 【发布时间】:2019-02-21 06:41:12 【问题描述】:我想在右键单击时选择一列,然后上下文菜单必须提供一个删除条目以删除选定的列。
使用 transportet QPoint arg 将鼠标位置发送到插槽。但我需要点击列。
如何解决?
【问题讨论】:
你可以提供一个minimal reproducible example,你在哪里点击:在标题中还是在视口中? 【参考方案1】:要获得该列,您必须使用通过 itemAt() 方法获得的按下项。
使用 setRangeSelected 方法通过传递 QTableWidgetSelectionRange 来选择它,该方法将列作为数据。
然后创建 QMenu 和 exec_() 方法,传递信号的位置,但必须使用视口中的 mapToGlobal 将其转换为全局。
然后使用 removeColumn() 方法删除该列。
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.table_widget = QtWidgets.QTableWidget(20, 10)
for i in range(self.table_widget.rowCount()):
for j in range(self.table_widget.columnCount()):
it = QtWidgets.QTableWidgetItem("-".format(i, j))
self.table_widget.setItem(i, j, it)
vlay = QtWidgets.QVBoxLayout(self)
vlay.addWidget(self.table_widget)
self.table_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.table_widget.customContextMenuRequested.connect(self.on_customContextMenuRequested)
@QtCore.pyqtSlot(QtCore.QPoint)
def on_customContextMenuRequested(self, pos):
it = self.table_widget.itemAt(pos)
if it is None: return
c = it.column()
item_range = QtWidgets.QTableWidgetSelectionRange(0, c, self.table_widget.rowCount()-1 , c)
self.table_widget.setRangeSelected(item_range, True)
menu = QtWidgets.QMenu()
delete_column_action = menu.addAction("Delete column")
action = menu.exec_(self.table_widget.viewport().mapToGlobal(pos))
if action == delete_column_action:
self.table_widget.removeColumn(c)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
【讨论】:
【参考方案2】:好的-根据您的解决方案(非常感谢)-我尝试了一个视图。主要是它做我想要的。如果我在表格主体中的单元格上单击鼠标右键,则应选择该单元格并应显示上下文菜单-好的-有效。如果行头或列头在鼠标光标下,则应选择整行(列) - 有效。
但是选择仍然存在,不应该是这样!
这是我的视图代码:
import logging
import sys
from PyQt5.QtWidgets import \
QApplication, QWidget, QVBoxLayout, QMenu, \
QTableWidget, QTableWidgetItem, QTableWidgetSelectionRange
from PyQt5.QtCore import \
QPoint, Qt
class View(QWidget):
def __init__(self, app, parent=None):
super().__init__(parent)
self.app = app
# gui elements
self.layout = None
self.tbl = None
self.tbl_selection = None
self.tbl_item = None
self.tbl_item_pos = [-1, -1]
def _setup_layout(self):
logging.debug("<View._setup_layout>")
self.setMinimumHeight(600)
self.setMinimumWidth(800)
self.layout = QVBoxLayout()
self.setLayout(self.layout)
def _setup_table(self):
logging.debug("<View._setup_table()>")
if self.app.data:
data = self.app.data
rows, cols = len(data), len(data[0])
self.tbl = tbl = QTableWidget(rows, cols)
tbl.setHorizontalHeaderLabels(data.pop(0))
for r, ds in enumerate(data):
for c, f in enumerate(ds):
item = QTableWidgetItem(f)
tbl.setItem(r, c, item)
def _setup_widgets(self):
logging.debug("<View._setup_widgets()>")
if self.app is not None:
self._setup_table()
else:
self.tbl = QTableWidget()
tbl = self.tbl
tbl.verticalHeader().setContextMenuPolicy(
Qt.CustomContextMenu)
tbl.horizontalHeader().setContextMenuPolicy(
Qt.CustomContextMenu)
self.layout.addWidget(self.tbl)
def _connect_evt_with_handler(self):
logging.debug("<View._connect_evt_with_handler()>")
tbl = self.tbl
tbl.setContextMenuPolicy(Qt.CustomContextMenu)
tbl.customContextMenuRequested.connect(self.on_tbl_rightclick)
# event for click on row heads
tbl.verticalHeader().customContextMenuRequested.connect(
self.on_tbl_rhead_rightclick)
# event for click on col heads
tbl.horizontalHeader().customContextMenuRequested.connect(
self.on_tbl_chead_rightclick)
# protected
def _get_clicked_item(self, qpoint: QPoint) -> bool:
logging.debug("<View._get_clicked_item(qpoint=)>".format(qpoint))
self.tbl_item = item = self.tbl.itemAt(qpoint)
self.tbl_item_pos = [item.row(), item.column()]
return self.tbl_item is not None
def _set_selection(self):
logging.debug("<View._set_selection()>")
r, c = self.tbl_item_pos
logging.debug("... row=, col=".format(r, c))
if r >= 0 and c >= 0:
self.tbl_selection = QTableWidgetSelectionRange(
r, c, r, c)
elif c < 0:
# row head
self.tbl_selection = QTableWidgetSelectionRange(
r, 0, r, self.tbl.columnCount() - 1)
elif r < 0:
# col head
self.tbl_selection = QTableWidgetSelectionRange(
0, c, self.tbl.rowCount() - 1, c)
self.tbl.setRangeSelected(self.tbl_selection, True)
def _build_ctx_mnu(self, qpoint: QPoint):
logging.debug("<View._build_ctx_mnu(qpoint=)>".format(qpoint))
r, c = self.tbl_item_pos
logging.debug("... row=, col=".format(r, c))
# build menu
action_del_col = None
action_del_row = None
menu = QMenu()
if c < 0:
# row head
action_del_row = menu.addAction("Delete row")
elif r < 0:
# col head
action_del_col = menu.addAction("Delete column")
else:
# table body
action_del_col = menu.addAction("Delete column")
action_del_row = menu.addAction("Delete row")
action = menu.exec_(self.tbl.viewport().mapToGlobal(qpoint))
if action is not None and action == action_del_col:
logging.debug("... action: ".format(action_del_col.text()))
self.tbl.removeColumn(c)
elif action is not None and action == action_del_row:
logging.debug("... action: ".format(action_del_row.text()))
self.tbl.removeRow(r)
# UI
def setup(self):
logging.debug("<View.setup()>")
self._setup_layout()
self._setup_widgets()
self._connect_evt_with_handler()
# events
def on_tbl_rightclick(self, qpoint: QPoint):
logging.debug("<View.on_tbl_rightclick(qpoint=)>".format(qpoint))
if self._get_clicked_item(qpoint):
self._set_selection()
self._build_ctx_mnu(qpoint)
def on_tbl_rhead_rightclick(self, qpoint: QPoint):
logging.debug(
"<View.on_tbl_rhead_rightclick(qpoint=)>".format(qpoint))
if self._get_clicked_item(qpoint):
self.tbl_item_pos[1] = -1
self._set_selection()
self._build_ctx_mnu(qpoint)
def on_tbl_chead_rightclick(self, qpoint: QPoint):
logging.debug(
"<View.on_tbl_chead_rightclick(qpoint=)>".format(qpoint))
if self._get_clicked_item(qpoint):
self.tbl_item_pos[0] = -1
self._set_selection()
self._build_ctx_mnu(qpoint)
这里是某个日期 - 再一次:
data = [f.strip().split(",") for f in """\
id,first_name,last_name,email,gender,ip_address
1,Hillard,Tasseler,htasseler0@google.com.br,Male,104.153.237.243
2,Tyrus,Oley,toley1@ft.com,Male,163.73.24.45
3,Kora,Covil,kcovil2@privacy.gov.au,Female,158.44.166.87
4,Phineas,McEntee,pmcentee3@rambler.ru,Male,71.82.246.45
5,Dottie,Spraging,dspraging4@berkeley.edu,Female,226.138.241.22
6,Andria,Ivatts,aivatts5@about.com,Female,57.5.76.78
7,Missy,Featherstone,mfeatherstone6@unblog.fr,Female,9.56.215.203
8,Anstice,Sargant,asargant7@about.me,Female,36.115.185.109
9,Teresita,Trounce,ttrounce8@myspace.com,Female,240.228.133.166
10,Sib,Thomke,sthomke9@ibm.com,Female,129.191.2.7
11,Amery,Dallander,adallandera@elpais.com,Male,4.115.194.100
12,Rourke,Rowswell,rrowswellb@bloomberg.com,Male,48.111.190.66
13,Cloe,Benns,cbennsc@slideshare.net,Female,142.48.24.44
14,Enos,Fery,eferyd@pen.io,Male,59.19.200.235
15,Russell,Capelen,rcapelene@fc2.com,Male,38.205.20.141""".split()]
以及用于测试:app 对象和主要功能:
class App:
def __init__(self, data=()):
self.view = View(app=self)
self.data = []
if isinstance(data, (list, tuple)) and len(data) > 0:
self.set(data)
def set(self, data):
logging.debug("<App.set(data)>")
self.data = data
def setup(self):
logging.debug("<App.setup()>")
self.view.setup()
def show(self):
logging.debug("<App.show()>")
self.view.show()
def main():
logging.basicConfig(level=logging.DEBUG)
qapp = QApplication(sys.argv)
app = App(data=data)
app.setup()
app.show()
sys.exit(qapp.exec_())
main()
【讨论】:
pyqt5qtablewidget详细用法
1.设置列数 列宽ui->tableWidget->setColumnCount(4);//设置列数ui->tableWidget->setColumnWidth(0,90); //0设置列宽ui->tableWidget->setColumnWidth(1,190);//1设置列宽ui->tableWidget->setColu 查看详情
如何在 PyQt5 中捕获 QTableWidget 上的左右鼠标单击事件?
】如何在PyQt5中捕获QTableWidget上的左右鼠标单击事件?【英文标题】:HowtocatchleftandrightmouseclickeventonQTableWidgetinPyQt5?【发布时间】:2020-09-2113:03:51【问题描述】:我创建了一个QTableWidget使用PyQt5和openpyxl在VSCode中加载excel,我无法... 查看详情
pyqt5 QTableWidget 仅在选择整行时删除行
】pyqt5QTableWidget仅在选择整行时删除行【英文标题】:pyqt5QTableWidgetdeletetherowonlywhenthewholerowisselected【发布时间】:2020-07-2105:45:36【问题描述】:我正在编写一个分析CSV文件的GUI,并且我想实现一个功能,其中只有在选择整行时才... 查看详情
对 QTableWidget 中的数字列进行排序
】对QTableWidget中的数字列进行排序【英文标题】:SortingnumericcolumninQTableWidget【发布时间】:2020-09-2119:13:28【问题描述】:我正在尝试使用PyQT5。我阅读了一些示例并进行了尝试,但效果不佳。它总是返回相同的结果。这是在排序... 查看详情
PyQt5 QTableWidget 禁用后如何重新启用单元格? [复制]
】PyQt5QTableWidget禁用后如何重新启用单元格?[复制]【英文标题】:PyQt5QTableWidgetHowtore-enableacellafterdisabling?[duplicate]【发布时间】:2020-06-0219:14:19【问题描述】:对于我的生活,我无法弄清楚这一点。我有一个表格,在第0行第0行... 查看详情
如何使用 PYQT5 使 QTableWidget 单元格只读?
】如何使用PYQT5使QTableWidget单元格只读?【英文标题】:HowtomakeQTableWidgetcellsreadonlyusingPYQT5?【发布时间】:2018-07-2109:36:09【问题描述】:我的对话框中有一个QTableWidget。我想让一些单元格只读。我如何使用PYQT5做到这一点?【问... 查看详情
PyQt5 更新/替换 QScrollArea 内的 QTableWidget
】PyQt5更新/替换QScrollArea内的QTableWidget【英文标题】:PyQt5update/replaceaQTableWidgetinsideaQScrollArea【发布时间】:2020-07-0707:40:23【问题描述】:我对基于Qt5的pythonGUI有疑问。我有一个元素来选择一个路径,然后是一个QScrollArea,其中显... 查看详情
PyQt5 QTableWidget 仅显示第一行和第一列
】PyQt5QTableWidget仅显示第一行和第一列【英文标题】:PyQt5QTableWidgetshowingonlyfirstlineandcolumn【发布时间】:2014-12-0913:33:19【问题描述】:我有一个QTableWidget填充列表列表。每个内部列表有八个元素,我的表有一个在加载其他元素后... 查看详情
在 QTableWidget PyQt5 中突出显示单元格
】在QTableWidgetPyQt5中突出显示单元格【英文标题】:HighlightCellinaQTableWidgetPyQt5【发布时间】:2017-11-2906:09:32【问题描述】:我有一个pyqt5QTableWidget,我想突出显示表格的特定单元格例如,我给出第2行和第2列,我希望该单元格突出... 查看详情
如何从 QComboBox 中获取所选项目以显示在 PyQt5 的 QTableWidget 中? (QComboBox 有复选框来选择项目)
】如何从QComboBox中获取所选项目以显示在PyQt5的QTableWidget中?(QComboBox有复选框来选择项目)【英文标题】:HowtogetselecteditemsfromQComboBoxtobedisplayedinQTableWidgetinPyQt5?(QComboBoxhascheckboxtopickitems)【发布时间】:2020-03-1022:47:26【问题描述... 查看详情
带有屏蔽密码列的 QTableWidget
】带有屏蔽密码列的QTableWidget【英文标题】:QTableWidgetwithamaskedpasswordcolumn【发布时间】:2020-12-0314:55:17【问题描述】:是否可以在我使用PyQt5创建的QTableWidget中屏蔽包含密码或列的某些单元格。我在这里找不到任何选项,搜索也... 查看详情
如何在 PyQt5 QTableWidget 中获取选定索引中的项目总和
】如何在PyQt5QTableWidget中获取选定索引中的项目总和【英文标题】:HowtogetthesumofitemsinselectedindexinPyQt5QTableWidget【发布时间】:2019-04-0305:03:20【问题描述】:我想获取currentRow中所选项目的总和,并在按下Enter键时将其显示在明显不... 查看详情
pythonpyqt5qtablewidget添加右键菜单
...例子\'\'\'importsysfromPyQt5.QtWidgetsimport(QMenu,QPushButton,QWidget,QTableWidget,QHBoxLayout,QApplication,QTableWidgetItem,QHeaderView)fromPyQt5.QtCoreimportQObject,QtclassTable(QWidget):ifname==\'main\':app=QApplication(sys.argv)example=Table()example.show()sys.exit(app.exec_()) 查看详情
Qtablewidget 去除黑色空间 PyQt5
】Qtablewidget去除黑色空间PyQt5【英文标题】:QtablewidgetremoveblackspacePyQt5【发布时间】:2018-04-1111:16:18【问题描述】:我正在尝试删除QTableWidget中的冗余空间。我正在使用PyQt5。这是代码self.tableWidget=QtWidgets.QTableWidget(self.centralwidget)... 查看详情
QTableWidget 上的 PYQT5 setCellWidget() 会减慢 UI
】QTableWidget上的PYQT5setCellWidget()会减慢UI【英文标题】:PYQT5setCellWidget()onQTableWidgetslowsdownUI【发布时间】:2020-02-2514:09:41【问题描述】:在QTableWidget()上使用PyQT5中的setCellWidget()时,我遇到了性能问题。一旦我的for-loop包含来自SQL... 查看详情
QTablewidget 在 PyQt5 中不显示新的 cellWidgets
】QTablewidget在PyQt5中不显示新的cellWidgets【英文标题】:QTablewidgetdoesn\'tshownewcellWidgetsinPyQt5【发布时间】:2017-09-0515:15:04【问题描述】:我的程序是用Python3.5和PyQt5编写的。我的类中有一个方法可以将一些自定义小部件添加到QTable... 查看详情
PyQt5:QTableWidget 与父窗口调整大小
】PyQt5:QTableWidget与父窗口调整大小【英文标题】:PyQt5:QTableWidgetrezizingwithparentwindow【发布时间】:2016-01-1914:34:21【问题描述】:我是使用PyQt5的初学者。我想在窗口底部创建一个带有tableWidget的对话框,其宽度与窗口宽度相同,... 查看详情
Pyqt5 qtablewidget 检测单元格何时更改
】Pyqt5qtablewidget检测单元格何时更改【英文标题】:Pyqt5qtablewidgetdetectwhenacellchanges【发布时间】:2021-03-0104:25:52【问题描述】:我在Python上的Pyqt5应用程序上有一个tableWidget。问题是我试图在特定单元格发生变化时连接到calculadora... 查看详情