Python - QTableWidget.selectedRanges() 返回多个选择范围
Posted
技术标签:
【中文标题】Python - QTableWidget.selectedRanges() 返回多个选择范围【英文标题】:Python - QTableWidget.selectedRanges() return multiple ranges for on selection 【发布时间】:2014-03-13 15:03:50 【问题描述】:我是 python 新手,开发了一个带有表格的 GUI。应该可以通过上下文菜单连接行和列。这有效。 我可以使用 ctrl + 鼠标左键选择多行。
但是表中有一个或多个跨度并且我想添加更多,如果选择 nXm 选择,QTableWidget.selectedRanges() 将返回 n*m selectionRanges。 例如,如果我在一列中选择了 3 行,则有 3 个 selectionRanges。
并且在控制台上写了3次
QTableView::setSpan: single cell span won't be added
已安装 Python 2.7.5+。
谢谢,再见。
2014 年 3 月 17 日编辑
这是我的小程序的完整代码。
程序.py
import sys
from PyQt4 import QtGui, QtCore
from tableGui import Ui_Dialog as Dlg
class MarkDownTableGui(QtGui.QDialog,Dlg):
def __init__(self):
QtGui.QDialog.__init__(self)
self.setupUi(self)
ColumnCount = None
ColumnRow = None
# Context menu connect cell/reset connected/selected cells
self.menu = QtGui.QMenu()
self.menu.addAction("Connect",self.addSpan)
self.menu.addAction("Reset",self.resetConnected)
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.showContextMenu)
self.connect(self.generateButton,QtCore.SIGNAL("clicked()"),self.onGenerate)
def onGenerate(self):
"""
Generate a m x n table
"""
self.tableWidget.setRowCount(self.RowCount.value())
self.tableWidget.setColumnCount(self.ColumnCount.value())
def addSpan(self):
selectedElements = self.tableWidget.selectedRanges()
for slrange in selectedElements:
self.tableWidget.setSpan(slrange.topRow(),slrange.leftColumn(),slrange.rowCount(),slrange.columnCount())
def showContextMenu(self,pos):
self.menu.exec_(QtGui.QCursor.pos())
def resetConnected(self):
#TODO
print "TODO"
app = QtGui.QApplication(sys.argv)
dialog = MarkDownTableGui()
dialog.show()
sys.exit(app.exec_())
这是tableGui.py,由pyuic4生成
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'dialog_Table.ui'
#
# Created: Mon Mar 17 08:59:43 2014
# by: PyQt4 UI code generator 4.10.3
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName(_fromUtf8("Dialog"))
Dialog.setWindowModality(QtCore.Qt.ApplicationModal)
Dialog.resize(509, 426)
Dialog.setModal(True)
self.buttonBox = QtGui.QDialogButtonBox(Dialog)
self.buttonBox.setGeometry(QtCore.QRect(140, 370, 341, 32))
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
self.ColumnCount = QtGui.QSpinBox(Dialog)
self.ColumnCount.setGeometry(QtCore.QRect(90, 10, 51, 23))
self.ColumnCount.setMinimum(1)
self.ColumnCount.setProperty("value", 5)
self.ColumnCount.setObjectName(_fromUtf8("ColumnCount"))
self.labelChapterCount = QtGui.QLabel(Dialog)
self.labelChapterCount.setGeometry(QtCore.QRect(10, 10, 74, 23))
self.labelChapterCount.setObjectName(_fromUtf8("labelChapterCount"))
self.RowCount = QtGui.QSpinBox(Dialog)
self.RowCount.setGeometry(QtCore.QRect(250, 10, 51, 23))
self.RowCount.setMinimum(1)
self.RowCount.setProperty("value", 5)
self.RowCount.setObjectName(_fromUtf8("RowCount"))
self.labelChapterCount_2 = QtGui.QLabel(Dialog)
self.labelChapterCount_2.setGeometry(QtCore.QRect(160, 10, 74, 23))
self.labelChapterCount_2.setObjectName(_fromUtf8("labelChapterCount_2"))
self.generateButton = QtGui.QPushButton(Dialog)
self.generateButton.setGeometry(QtCore.QRect(340, 10, 111, 24))
self.generateButton.setObjectName(_fromUtf8("generateButton"))
self.tableWidget = QtGui.QTableWidget(Dialog)
self.tableWidget.setGeometry(QtCore.QRect(0, 40, 491, 321))
self.tableWidget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self.tableWidget.setRowCount(5)
self.tableWidget.setColumnCount(5)
self.tableWidget.setObjectName(_fromUtf8("tableWidget"))
self.retranslateUi(Dialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Dialog.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(_translate("Dialog", "Table editor", None))
self.labelChapterCount.setText(_translate("Dialog", "Column", None))
self.labelChapterCount_2.setText(_translate("Dialog", "Rows", None))
self.generateButton.setText(_translate("Dialog", "generate Table", None))
问题
-
如果程序正在运行,您可以按住鼠标左键选择单元格
左键单击打开上下文菜单
选择连接,创建列/行跨度
如果我想添加额外的跨度并从第 1 点开始。然后我再次收到消息
QTableView::setSpan:不会添加单个单元格跨度
问题是为什么 selectedRanges() 返回一个带有 n selectionRanges 的列表,而不是仅在 selectionRange 上。我已经阅读了QTableWidget 和QTableSelectionRange 的文档。但是没有任何想法
【问题讨论】:
你能澄清你的问题吗?从您迄今为止提供的信息中,很难判断问题是什么,或者您要求什么。 我已经编辑了我的初始帖子。我希望它能提高对问题的理解。 【参考方案1】:似乎跨越表格中的单元格会改变选择模型构建其选择范围的方式。我不知道为什么会这样,但即使没有发生,也不会消除所有问题。
默认情况下,table-widget 允许多个选择,因此您最终会得到一个无法跨越的选择(作为一个整体)。但即使多个选择彼此相邻并形成一个可以跨越的块,选择模型将总是将这些记录为选择范围列表,而不是将它们全部合并到一个选择中。
因此,要使其正常工作,我认为您必须先切换到不同的选择模式,然后才能设置跨度。最好的选择似乎是这样的:
self.tableWidget.setSelectionMode(
QtGui.QAbstractItemView.ContiguousSelection)
只允许选择单个矩形块。可能您需要一个按钮来在不同的选择模式之间切换,并酌情禁用“连接”菜单项。
这仍然存在在设置第一个跨度后处理选择范围列表的问题。要解决此问题,您可以执行以下操作:
def addSpan(self):
selection = list(self.tableWidget.selectionModel().selection())
selection.sort()
top = selection[0].top()
left = selection[0].left()
bottom = selection[-1].bottom()
right = selection[-1].right()
self.tableWidget.setSpan(
top, left, bottom - top + 1, right - left + 1)
我不确定是否真的需要对选择进行排序,但它确实可以保证选择范围始终处于正确的顺序。
【讨论】:
以上是关于Python - QTableWidget.selectedRanges() 返回多个选择范围的主要内容,如果未能解决你的问题,请参考以下文章