如何从单元格QTableView中获取纯文本



我试图在两个项目之间进行拖放,但是我在表格中单击的单元格中获取信息时遇到了麻烦。我有一个自定义表,它有一个自定义模型。

class PyTableWidget(QTableView):
def __init__(self, *args):
super().__init__()
self.setDragEnabled(True)
self.set_stylesheet(*args)
def onLeftClick(self, index):
print('onClick index.row: %s, index.col: %s' % (index.row(), index.column()))
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
drag = QDrag(self)
mime = QMimeData()
drag.setMimeData(mime)
drag.exec(Qt.MoveAction)

下面是表的自定义模型:

class CustomizedNumpyModel(QAbstractTableModel):
def __init__(self, data, parent=None):
QAbstractTableModel.__init__(self, parent)
self._data = np.array(data.values)
self._cols = data.columns
self.r, self.c = np.shape(self._data)
def data(self, index, role=Qt.DisplayRole):
if role == Qt.DisplayRole:
value = self._data[index.row(), index.column()]
if isinstance(value, float):
return "%.2f" % value
if isinstance(value, str):
return '%s' % value
return unicode(value)
def rowCount(self, parent=None):
return self.r
def columnCount(self, parent=None):
return self.c
def headerData(self, p_int, orientation, role):
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
return str(self._cols[p_int])
if orientation == Qt.Vertical:
return p_int
return None
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def setData(self, index, value, role=Qt.EditRole):
index_value = None
based_columns = [6, 8, 10, 12]
if role == Qt.EditRole:
row = index.row()
column = index.column()
tmp = str(value)
if tmp != '':
if column in based_columns:
if column == 6 and tmp in self._cols:
index_no = np.where(self._cols == tmp)[0][0]
self._data[row, column + 1] = self._data[row, index_no]
self._data[row, column] = tmp
elif column in [8, 10, 12]:
for x in range(97, 181):
if self._data[row, x] == int(tmp):
index_value = x
break
col_name = self._cols[index_value]
col_name = col_name.removesuffix('_rank')
self._data[row, column + 1] = col_name
self._data[row, column] = tmp
self.dataChanged.emit(index, index)
return True
else:
return False

这里是接受drop

的其他小部件中的代码
class PyCustomButton(QPushButton):
def __init__(self, *args):
super().__init__()
self.setCursor(Qt.PointingHandCursor)
self.setAcceptsDrops(True)
self._lista = []
def dragEnterEvent(self, event):
if event.mimeData().hasText():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
self._lista.append(event.mimeData().text())
print(self._lista)

表有以下方面:

tbody> <<tr>
Names
第一个
第二

简单的解决方案是获取" selected ";索引使用indexAt()。请注意,通常最好在用户将鼠标移动一定像素(默认为QApplicationstartDragDistance()属性)时启动拖动操作。

class PyTableWidget(QTableView):
_startPos = None
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
index = self.indexAt(event.pos())
if index.isValid():
self._startPos = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton and self._startPos is not None:
delta = (event.pos() - self._startPos).manhattanLength()
if delta >= QApplication.startDragDistance():
drag = QDrag(self)
mime = QMimeData()
mime.setText(self.indexAt(self._startPos).data())
drag.setMimeData(mime)
drag.exec(Qt.MoveAction)
self._startPos = None
return
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
self._startPos = None
super().mouseReleaseEvent(event)

注意Qt项目视图已经支持拖放:为了在自定义模型中启用支持,您还需要在flags()中添加Qt.ItemIsDragEnabled,并确保表支持通过使用setDragEnabled(True)(如您所做的)或通过将视图的dragDropMode至少设置为DragOnly来拖动。

唯一剩下的"问题">是否从视图外部的拖动mime数据中获取数据,该数据使用内部格式来序列化内容。

虽然这种方法可能看起来更复杂和困难,它也是一个更好的解决方案,当你打算支持多个项目视图之间的拖放,因为序列化格式是通用的和标准的所有Qt视图。

class CustomizedNumpyModel(QAbstractTableModel):
# ...
def flags(self, index):
return (Qt.ItemIsEnabled 
| Qt.ItemIsSelectable 
| Qt.ItemIsEditable 
| Qt.ItemIsDragEnabled)

class PyTableWidget(QTableView):
def __init__(self, *args):
super().__init__(*args)
self.setDragEnabled(True)
# nothing else to implement in this class

class PyCustomButton(QPushButton):
def __init__(self, *args):
super().__init__()
self.setCursor(Qt.PointingHandCursor)
self.setAcceptDrops(True)
self._lista = []
def dragEnterEvent(self, event):
if 'application/x-qabstractitemmodeldatalist' in event.mimeData().formats():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
mimeData = event.mimeData()
if mimeData.hasText():
self._lista.append(mimeData.text())
elif 'application/x-qabstractitemmodeldatalist' in mimeData.formats():
names = []
stream = QDataStream(mimeData.data(
'application/x-qabstractitemmodeldatalist'))
while not stream.atEnd():
# all fields must be read, even if not used
row = stream.readInt()
column = stream.readInt()
for _ in range(stream.readInt()):
role = stream.readInt()
value = stream.readQVariant()
if role == Qt.DisplayRole:
names.append(value)
self._lista.extend(names)
print(self._lista)

注意setData()必须始终返回bool值。删除最后一个else:,并将return False推回到函数的主缩进级别。

最新更新