- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我几乎在 QTreeView 中有一个完全有效的拖放重新排序。除了掉落的对象从未出现之外,一切似乎都很好(尽管我可以通过多种不同的方式来引用它,向我证明它确实存在于它应该在的地方)。如果有人有时间并且可以运行以下代码并让我知道我做错了什么,我将非常感激。一个多星期以来,我一直在反对这个过程:
您应该能够复制并运行以下代码(我有一堆打印语句,似乎表明一切正常,但显然有些问题):
import sys
from PyQt4 import QtGui
from PyQt4 import QtCore
################################################################################
class Branch(object):
"""
Basic branch/leaf node.
"""
#---------------------------------------------------------------------------
def __init__(self, name, value, parent=None):
"""
Constructor.
"""
super(Branch, self).__init__()
#name and parent are both to be stored directly as variables
self.name = name
self.parent = parent
self.value = value
#store sub-objects (usually other branches)
self.objD = dict()
self.nameL = list()
#---------------------------------------------------------------------------
def get_name(self):
"""
Getter.
"""
return self.name
#---------------------------------------------------------------------------
def get_parent(self):
"""
Returns the parent of this object.
"""
return self.parent
#---------------------------------------------------------------------------
def set_value(self, value):
"""
Generic setter for all settings.
"""
self.value = value
#---------------------------------------------------------------------------
def get_value(self):
"""
Generic getter for all settings. Returns the display value
"""
return self.value
#---------------------------------------------------------------------------
def add_child_obj(self, obj, row=None):
"""
Adds the param object to the dict and list.
"""
self.objD[obj.get_name()] = obj
if row == None:
self.nameL.append(obj.get_name())
else:
self.nameL.insert(row, obj.get_name())
print "JUST ADDED CHILD AT ROW:", self.nameL.index(obj.get_name())
#---------------------------------------------------------------------------
def remove_child_at_row(self, row):
"""
Removes the param object from the dict and list.
"""
childName = self.nameL[row]
del(self.nameL[row])
del(self.objD[childName])
#---------------------------------------------------------------------------
def get_child_count(self):
"""
Returns the number of children in this branch.
"""
return len(self.nameL)
#---------------------------------------------------------------------------
def get_child_list(self):
"""
Returns a list of the visible children names.
"""
return self.nameL
#---------------------------------------------------------------------------
def get_child_at_row(self, row):
"""
Returns a specific child object based on its ordinal (only consider
visible children).
"""
childName = self.nameL[row]
return self.objD[childName]
#---------------------------------------------------------------------------
def get_child_by_name(self, childName):
"""
Returns a specific child object based on its name.
"""
return self.objD[childName]
#---------------------------------------------------------------------------
def get_index(self):
"""
Returns this object's index position with regard to its siblings.
"""
siblingsL = self.parent.get_child_list()
return siblingsL.index(self.get_name())
################################################################################
class MyTreeView(QtGui.QTreeView):
"""
Overrides the QTreeView to handle keypress events.
"""
#---------------------------------------------------------------------------
def __init__(self, model, parent=None):
"""
Constructor for the TreeView class.
"""
super(MyTreeView, self).__init__(parent)
self.setModel(model)
################################################################################
class MyTreeModel(QtCore.QAbstractItemModel):
"""
My tree view data model
"""
#---------------------------------------------------------------------------
def __init__(self, root):
"""
Constructor for the TreeModel class
"""
super(MyTreeModel, self).__init__()
self.root = root
self.fontSize = 8
self.selection = None
#---------------------------------------------------------------------------
def columnCount(self, index=QtCore.QModelIndex()):
"""
Returns the number of columns in the treeview.
"""
return 1
#---------------------------------------------------------------------------
def rowCount(self, index=QtCore.QModelIndex()):
"""
Returns the number of children of the current index obj.
"""
if index.column() > 0:
return 0
if not index.isValid():
item = self.root
else:
item = index.internalPointer()
if item:
return item.get_child_count()
return 0
#---------------------------------------------------------------------------
def index(self, row, column, parent):
"""
Returns a QModelIndex item for the current row, column, and parent.
"""
if not self.hasIndex(row, column, parent):
return QtCore.QModelIndex()
if not parent.isValid():
parentItem = self.root
else:
parentItem = parent.internalPointer()
childItem = parentItem.get_child_at_row(row)
if childItem:
return self.createIndex(row, column, childItem)
else:
return QtCore.QModelIndex()
#---------------------------------------------------------------------------
def parent(self, index):
"""
Returns a QModelIndex item for the parent of the given index.
"""
if not index.isValid():
return QtCore.QModelIndex()
childItem = index.internalPointer()
if not childItem:
return QtCore.QModelIndex()
parentItem = childItem.get_parent()
if parentItem == self.root:
return QtCore.QModelIndex()
return self.createIndex(parentItem.get_index(), 0, parentItem)
#---------------------------------------------------------------------------
def data(self, index, role=QtCore.Qt.DisplayRole):
"""
Returns the text or formatting for a particular cell, depending on the
role supplied.
"""
#invalid indexes return invalid results
if not index.isValid():
return QtCore.QVariant()
#access the underlying referenced object
item = index.internalPointer()
#edit role displays the raw values
if role == QtCore.Qt.EditRole:
return item.get_value()
#return the data to display
if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
return item.get_value()
return QtCore.QVariant()
#---------------------------------------------------------------------------
def headerData(self, index, orientation, role=QtCore.Qt.DisplayRole):
"""
Returns the text for the horizontal headers (parameter names)
"""
if role == QtCore.Qt.TextAlignmentRole:
if orientation == QtCore.Qt.Horizontal:
alignment = int(QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
return QtCore.QVariant(alignment)
alignment = int(QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
return QtCore.QVariant(alignment)
if role != QtCore.Qt.DisplayRole:
return QtCore.QVariant()
if orientation == QtCore.Qt.Horizontal:
if int(index) == 0:
return "Name"
#---------------------------------------------------------------------------
def supportedDropActions(self):
"""
We allow re-ordering.
"""
return QtCore.Qt.MoveAction
#---------------------------------------------------------------------------
def flags(self, index):
"""
Returns whether or not the current item is editable/selectable/etc.
"""
if not index.isValid():
return QtCore.Qt.ItemIsEnabled
#by default, you can't do anything
enabled = QtCore.Qt.ItemIsEnabled
selectable = QtCore.Qt.ItemIsSelectable
editable = QtCore.Qt.ItemIsEditable
draggable = QtCore.Qt.ItemIsDragEnabled
droppable = QtCore.Qt.ItemIsDropEnabled
#return our flags.
return enabled | selectable| editable| draggable| droppable
#---------------------------------------------------------------------------
def setData(self, index, value, role=QtCore.Qt.EditRole):
"""
Sets the data.
"""
#convert the value into a string
if value:
item = index.internalPointer()
item.set_value(value)
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
index, index)
return True
#---------------------------------------------------------------------------
def supportedDropActions(self):
"""
Only allow moves
"""
return QtCore.Qt.MoveAction
#---------------------------------------------------------------------------
def mimeTypes(self):
"""
Only accept the internal custom drop type which is plain text
"""
types = QtCore.QStringList()
types.append('text/plain')
return types
#---------------------------------------------------------------------------
def mimeData(self, index):
"""
Wrap the index up as a list of rows and columns of each
parent/grandparent/etc
"""
rc = ""
theIndex = index[0] #<- for testing purposes we only deal with 1st item
while theIndex.isValid():
rc = rc + str(theIndex.row()) + ";" + str(theIndex.column())
theIndex = self.parent(theIndex)
if theIndex.isValid():
rc = rc + ","
mimeData = QtCore.QMimeData()
mimeData.setText(rc)
return mimeData
#---------------------------------------------------------------------------
def dropMimeData(self, data, action, row, column, parentIndex):
"""
Extract the whole ancestor list of rows and columns and rebuild the
index item that was originally dragged
"""
if action == QtCore.Qt.IgnoreAction:
return True
if data.hasText():
ancestorL = str(data.text()).split(",")
ancestorL.reverse() #<- stored from the child up, we read from ancestor down
pIndex = QtCore.QModelIndex()
for ancestor in ancestorL:
srcRow = int(ancestor.split(";")[0])
srcCol = int(ancestor.split(";")[1])
itemIndex = self.index(srcRow, srcCol, pIndex)
pIndex = itemIndex
item = itemIndex.internalPointer()
parent = parentIndex.internalPointer()
#modify the row if it is -1 (we want to append to the end of the list)
if row == -1:
row = parent.get_child_count()
self.beginInsertRows(parentIndex, row-1, row)
print "------------------"
parentIndex.internalPointer().add_child_obj(item)
print "------------------"
self.endInsertRows()
print "sanity check:"
print "dragged Node", item.get_name()
print "parent Node", parent.get_name()
print "inserted at row",row
print "inserted Node:",parent.get_child_at_row(row).get_name()
print row, column
print "from index():",self.index(row, 0, parentIndex).internalPointer().get_name()
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
self.index(row, 0, parentIndex),
self.index(row, 0, parentIndex))
return True
#---------------------------------------------------------------------------
def insertRow(self, row, parent):
print "insertRow"
return self.insertRows(row, 1, parent)
#---------------------------------------------------------------------------
def insertRows(self, row, count, parent):
print "insertRows"
self.beginInsertRows(parent, row, (row + (count - 1)))
self.endInsertRows()
return True
#---------------------------------------------------------------------------
def removeRow(self, row, parentIndex):
print "removeRow"
return self.removeRows(row, 1, parentIndex)
#---------------------------------------------------------------------------
def removeRows(self, row, count, parentIndex):
self.beginRemoveRows(parentIndex, row, row)
print "about to remove child at row:",row
print "which is under the parent named:",parentIndex.internalPointer().get_name()
print "and whose own name is:",parentIndex.internalPointer().get_child_at_row(row).get_name()
parentIndex.internalPointer().remove_child_at_row(row)
self.endRemoveRows()
return True
class Ui_MainWindow(object):
def printChildren(self, item):
print item.name
for child in item.get_child_list():
self.printChildren(item.get_child_by_name(child))
def printit(self):
self.printChildren(self.root)
def setupUi(self, MainWindow):
root = Branch("root", "root", QtCore.QVariant)
item1 = Branch("ITEM1","ITEM1",root)
item2 = Branch("ITEM2","ITEM2",root)
item3 = Branch("ITEM3","ITEM3",root)
root.add_child_obj(item1)
root.add_child_obj(item2)
root.add_child_obj(item3)
item1a = Branch("thinga","thinga",item1)
item1b = Branch("thingb","thingb",item1)
item1.add_child_obj(item1a)
item1.add_child_obj(item1b)
item2a = Branch("thingc","thingc",item2)
item2b = Branch("thingd","thingd",item2)
item2.add_child_obj(item2a)
item2.add_child_obj(item2b)
item3a = Branch("thinge","thinge",item3)
item3b = Branch("thingf","thingf",item3)
item3.add_child_obj(item3a)
item3.add_child_obj(item3b)
item1a1 = Branch("___A","___A",item1a)
item1a2 = Branch("___B","___B",item1a)
item1a.add_child_obj(item1a1)
item1a.add_child_obj(item1a2)
item1b1 = Branch("___C","___C",item1b)
item1b2 = Branch("___D","___D",item1b)
item1b.add_child_obj(item1b1)
item1b.add_child_obj(item1b2)
item2a1 = Branch("___E","___E",item2a)
item2a2 = Branch("___F","___F",item2a)
item2a.add_child_obj(item2a1)
item2a.add_child_obj(item2a2)
item2b1 = Branch("___G","___G",item2b)
item2b2 = Branch("___H","___H",item2b)
item2b.add_child_obj(item2b1)
item2b.add_child_obj(item2b2)
item3a1 = Branch("___J","___J",item3a)
item3a2 = Branch("___K","___K",item3a)
item3a.add_child_obj(item3a1)
item3a.add_child_obj(item3a2)
item3b1 = Branch("___L","___L",item3b)
item3b2 = Branch("___M","___M",item3b)
item3b.add_child_obj(item3b1)
item3b.add_child_obj(item3b2)
self.root = root
MainWindow.setObjectName("MainWindow")
MainWindow.resize(600, 400)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.myModel = MyTreeModel(root)
self.treeView = MyTreeView(self.myModel, self.centralwidget)
self.treeView.setObjectName("treeView")
self.treeView.dragEnabled()
self.treeView.acceptDrops()
self.treeView.showDropIndicator()
self.treeView.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
self.treeView.expandAll()
self.horizontalLayout.addWidget(self.treeView)
self.btn = QtGui.QPushButton('print', MainWindow)
MainWindow.connect(self.btn, QtCore.SIGNAL("clicked()"), self.printit)
self.horizontalLayout.addWidget(self.btn)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 600, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
最佳答案
这并不能解决所有问题,但将 dropMimeData() 更改为以下内容至少将允许移动叶项。
self.beginInsertRows(parentIndex, row, row)
parentIndex.internalPointer().add_child_obj(Branch(item.get_name(), item.get_value(), parent), row)
self.endInsertRows()
关于qt: pyqt: QTreeView 内部拖放几乎可以正常工作...拖动的项目消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4252114/
有人知道如何为 QTreeView 项目的子组实现/实现具有不同颜色的 QTreeView 吗? 像这样的东西: 有没有人做过类似的事情,可以给我一个教程或操作方法的链接,或者示例代码也不错。目前我完
在 Qt 文档中 http://doc.qt.io/qt-5/model-view-programming.html#model-subclassing-reference ,据说,如果你的模型是可排
我正在使用 Qt 4.7.0,一个多列的 Qtreeview。 我想要做的是“简单”:我想要一条线增加它的高度 , 当它被选中时。 代表是否足以做到这一点? 我已经通过 QTableView 经历了一
我需要在 QTreeView 中通过拖放来实现行移动,并在行之间显示放置指示器。我想知道是否有一种方法可以覆盖指标绘图,因此它仅针对行之间的所有层次结构显示(不是项目周围的矩形),该行必须与整行一样宽
我现在正在测试 QTreeView 功能,我对一件事感到惊讶。似乎 QTreeView 内存消耗取决于项目数 O_O。这是非常不寻常的,因为这种类型的模型 View 容器只跟踪显示的项目,其余项目都在
我正在尝试让 QTreeView(使用底层 QFileSystemModel)显示目录树。如果我将 RootPath 设置为父目录,那么我会看到所有子目录,但看不到父目录。如果我将 RootPath
我尝试编写一个基于 QTreeView 的可编辑表格,在单元格中包含自动换行的内容,而这些单元格又应该像 MSWord 中表格中的普通单元格一样扩展高度(整个文本可见),但遇到了无法克服的障碍: 首先
我想要一个 TreeView ,它在各个列中显示项目名称、项目描述和两个相关的 bool 值。我首先修改 Editable Tree Mode example ,所以有一个 TreeModel 跟踪一
我想在我的程序中实现一个带有嵌套子级别的树,我正在寻找这两种( View /小部件)中的哪一种最适合我的目标。 我有一个任务完成/错过/失败的天数列表,每个任务都有完成/错过/失败的次数,最后是当天的
我想要我的 QTreeView总是展开所有的项目。在这种情况下,所有展开按钮/装饰都是不必要的,我想摆脱它们。我怎样才能删除所有这些? setRootIsDecorated只会删除第一级的按钮....
我有一个 QTreeView 子类(和 QAbstractItemModel 子类),它有一个漂亮的水平标题。我想添加垂直标题(从左侧向下)以匹配。但与具有单独的垂直 ( setVerticalHea
我想在 Qt 中实现对 QTreeView 对象的手动控制。 (这意味着将对一切进行编程控制,包括导航)到目前为止,我已经在 sibling 中实现了导航/选择。但是,我想建立一个更容易控制的状态,无
我想在 Qt 中实现对 QTreeView 对象的手动控制。 (这意味着将对一切进行编程控制,包括导航)到目前为止,我已经在 sibling 中实现了导航/选择。但是,我想建立一个更容易控制的状态,无
我有需要在 QTreeView 中显示的自定义数据。我从 QAbstractTableModel 派生了我的模型,并制作了自己的 rowCount()、columnCount()、data() 和 h
我的小部件中有一个QTreeView。当在 View 中选择一个项目时,我有 在详细信息窗口中更新一系列信息小部件的信号处理程序 关于所选项目。然后,用户可以编辑项目详细信息并提交 更改回模型。 更改
在下面的代码中,QTreeView 小部件始终占用最大空间,并为 QPushButton 小部件留下最小空间(代码后的图像)。如果 QTreeView 小部件被另一个 QPushButton 替换(当
我正在使用 Qt4,我正在尝试显示带有 QTreeView 的模型。我拥有的模型由多个批处理过程组成,每个批处理都有一些元素,每个元素都有一些子元素(同一批元素具有相同数量的子元素,但我认为这与问题无
我有一个 qt 对象 QTreeView我想切换标签位置。基本上我有一个填充的 TreeView。和功能 columnViewportPosition ( int column ) 第一列返回 0,第
我目前正在尝试制作一个 QTreeView 来显示计算机上文件夹的内容。但是,我遇到了一些奇怪的问题,其中 .和 .. 显示在 TreeView 中,我不希望这种情况发生。我该如何禁用显示 .以及 .
我在从 QTreeWidget 迁移到 QtreeView 时遇到问题。对于 QTreeWidget 来说显而易见且微不足道的事情在 View 中似乎是不可能的。具体来说:我有一个带有 TreeVie
我是一名优秀的程序员,十分优秀!