我创建了一个自定义QListWidget,并将自定义列表窗口小部件(在本例中仅为QPushButton小部件)添加到QListWidgetItems中,并进行了所有设置,以便我可以从QPushButton拖放,以向QListWidget添加另一个按钮。在第一个列表小部件中,您会注意到在两个列表小部件之间有一条虚线,表示您可以在两个现有小部件之间拖动和插入一个小部件。但是,使用我的自定义列表,我已经失去了这种行为。我仍然可以将它们放在现有的小部件之间,但是像以前一样,用户看不到要插入两个小部件之间的水平条。有谁知道我会怎么做?您可以在下图中看到第一个列表中的行,该行是在两者之间插入项目的默认指示符。红色箭头指向我要创建的自定义插入指示器。
其次,当我从自定义QPushButton拖放时,它突出显示为黑色,但再也没有恢复为正常的灰色,如上图所示。我如何将这个按钮恢复为默认状态?
from inspect import isclass
from shiboken2 import wrapInstance
from PySide2 import QtCore, QtGui, QtWidgets
from maya import OpenMayaUI as omui
def show_ui():
main_win_obj = omui.MQtUtil.mainWindow()
main_win = wrapInstance(long(main_win_obj), QtWidgets.QWidget)
win = Test(parent=main_win)
win.show()
class DragButton(QtWidgets.QPushButton):
def __init__(self, parent=None, text=''):
super(DragButton, self).__init__()
self.setText(text)
def mouseMoveEvent(self, event):
if event.buttons() != QtCore.Qt.LeftButton:
super(DragButton, self).mouseMoveEvent(event)
return
btn_img = self.grab()
painter = QtGui.QPainter(btn_img)
painter.setCompositionMode(
painter.CompositionMode_DestinationIn
)
painter.fillRect(btn_img.rect(), QtGui.QColor(0, 0, 0, 127))
painter.end()
data = QtCore.QMimeData()
data.setText('ReorderListAdd()')
drag = QtGui.QDrag(self)
drag.setMimeData(data)
drag.setPixmap(btn_img)
drag.setHotSpot(event.pos())
drag.exec_(QtCore.Qt.CopyAction)
super(DragButton, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
data = QtCore.QMimeData()
data.setText('my text')
drag = QtGui.QDrag(self)
drag.setMimeData(data)
drag.exec_()
super(DragButton, self).mouseReleaseEvent(event)
class ReorderList(QtWidgets.QListWidget):
def __init__(self, parent=None):
super(ReorderList, self).__init__(parent)
self.setDragDropMode(
QtWidgets.QAbstractItemView.InternalMove
)
self.setAcceptDrops(True)
self.setAlternatingRowColors(True)
self.setSelectionMode(
QtWidgets.QAbstractItemView.SingleSelection
)
self.setDragDropMode(
QtWidgets.QAbstractItemView.InternalMove
)
def add_btn(self, text='', index=-1):
widget = QtWidgets.QWidget()
if not text:
text = 'item {0}'.format(self.count() + 1)
btn = QtWidgets.QPushButton(text)
layout = QtWidgets.QVBoxLayout(widget)
layout.setContentsMargins(2, 2, 2, 2)
layout.setSpacing(2)
layout.addWidget(btn)
item = QtWidgets.QListWidgetItem()
item.setSizeHint(widget.sizeHint())
if index < 0:
self.addItem(item)
else:
self.insertItem(index, item)
self.setItemWidget(item, widget)
def dropEvent(self, event):
drop_index = self.indexAt(event.pos()).row()
self.add_btn(index=drop_index)
super(ReorderList, self).dropEvent(event)
def dragEnterEvent(self, event):
event.accept()
def dragMoveEvent(self, event):
event.accept()
def onClick(self):
print self.sender().text()
class Test(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(Test, self).__init__(*args, **kwargs)
self.list1 = QtWidgets.QListWidget()
self.list1.setDragDropMode(
QtWidgets.QAbstractItemView.DragDrop
)
self.list1.setSelectionMode(
QtWidgets.QAbstractItemView.SingleSelection
)
self.list1.setDragDropMode(
QtWidgets.QAbstractItemView.InternalMove
)
self.list1.setMaximumHeight(60)
self.list2 = ReorderList()
self.list2.setMaximumHeight(120)
for name in ('item 1', 'item 2', 'item 3'):
item = QtWidgets.QListWidgetItem(name)
self.list1.addItem(item)
self.list2.add_btn(text=name)
self.btn = DragButton(text='Add list button')
self.btn.clicked.connect(self.list2.add_btn)
self.widget = QtWidgets.QWidget()
self.setCentralWidget(self.widget)
self.layout = QtWidgets.QVBoxLayout(self.widget)
for item in (self.list1, self.list2, self.btn):
self.layout.addWidget(item)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
win = Test()
win.show()
sys.exit(app.exec_())
我希望在QListWidget中插入小部件时能够有一个水平条,并且使已经被毒品使用的按钮恢复为默认颜色。
以下是我可以找到的一些类似链接:
答案 0 :(得分:1)
由于拖放是自定义的,因此必须进行绘画,为此必须使用dragMoveEvent方法中的QModelIndex检测项目的矩形。然后进行绘画,但是由于小部件的大小,将看不到它,所以我看了一下,我创建了一个修改编辑器几何形状的委托。
class Delegate(QtWidgets.QStyledItemDelegate):
def updateEditorGeometry(self, editor, option, index):
super(Delegate, self).updateEditorGeometry(editor, option, index)
geo = editor.geometry().adjusted(0, 4, 0, 0)
editor.setGeometry(geo)
class ReorderList(QtWidgets.QListWidget):
def __init__(self, parent=None):
super(ReorderList, self).__init__(parent)
delegate = Delegate(self)
self.setItemDelegate(delegate)
self.dropIndicatorRect = QtCore.QRect()
self.setDragDropMode(
QtWidgets.QAbstractItemView.InternalMove
)
self.setAcceptDrops(True)
self.setAlternatingRowColors(True)
self.setSelectionMode(
QtWidgets.QAbstractItemView.SingleSelection
)
self.setDragDropMode(
QtWidgets.QAbstractItemView.InternalMove
)
def add_btn(self, text='', index=-1):
widget = QtWidgets.QWidget()
if not text:
text = 'item {0}'.format(self.count() + 1)
btn = QtWidgets.QPushButton(text)
item = QtWidgets.QListWidgetItem()
item.setSizeHint(btn.sizeHint())
if index < 0:
self.addItem(item)
else:
self.insertItem(index, item)
self.setItemWidget(item, btn)
def dropEvent(self, event):
drop_index = self.indexAt(event.pos()).row()
self.add_btn(index=drop_index)
self.dropIndicatorRect = QtCore.QRect()
self.viewport().update()
super(ReorderList, self).dropEvent(event)
def dragEnterEvent(self, event):
event.accept()
def dragLeaveEvent(self, event):
self.dropIndicatorRect = QtCore.QRect()
self.viewport().update()
super(ReorderList, self).dragLeaveEvent(event)
def dragMoveEvent(self, event):
event.accept()
def onClick(self):
print(self.sender().text())
def dragMoveEvent(self, event):
index = self.indexAt(event.pos())
if index.isValid():
rect = self.visualRect(index)
if self.dropIndicatorPosition() == QtWidgets.QAbstractItemView.OnItem:
self.dropIndicatorRect = rect
else:
self.dropIndicatorRect = QtCore.QRect()
else:
self.dropIndicatorRect = QtCore.QRect()
self.viewport().update()
super(ReorderList, self).dragMoveEvent(event)
def paintEvent(self, event):
super(ReorderList, self).paintEvent(event)
if not self.dropIndicatorRect.isNull() and self.showDropIndicator():
painter = QtGui.QPainter(self.viewport())
p = QtGui.QPen(painter.pen())
p.setWidthF(1.5)
painter.setPen(p)
r = self.dropIndicatorRect
painter.drawLine(r.topLeft(), r.topRight())
答案 1 :(得分:0)
我不确定我是否正确理解您,但请尝试以下示例:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class DragButton(QtWidgets.QPushButton):
def __init__(self, *args, **kwargs):
super(DragButton, self).__init__(*args, **kwargs)
def mouseMoveEvent(self, event):
if event.buttons() != QtCore.Qt.LeftButton:
super(DragButton, self).mouseMoveEvent(event)
return
# btn_img = QtGui.QPixmap.grabWidget(self) # ---
btn_img = self.grab() # +++
painter = QtGui.QPainter(btn_img)
painter.setCompositionMode(
painter.CompositionMode_DestinationIn
)
painter.fillRect(btn_img.rect(), QtGui.QColor(0, 0, 0, 127))
painter.end()
data = QtCore.QMimeData()
data.setText('ReorderListAdd()')
drag = QtGui.QDrag(self)
drag.setMimeData(data)
drag.setPixmap(btn_img)
drag.setHotSpot(event.pos())
drag.exec_(QtCore.Qt.CopyAction)
super(DragButton, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
data = QtCore.QMimeData()
data.setText('my text')
drag = QtGui.QDrag(self)
drag.setMimeData(data)
drag.exec_()
super(DragButton, self).mouseReleaseEvent(event)
class ReorderList(QtWidgets.QListWidget):
def __init__(self, parent=None):
super(ReorderList, self).__init__(parent)
self.setDragDropMode(
QtWidgets.QAbstractItemView.InternalMove
)
self.setAcceptDrops(True)
self.setAlternatingRowColors(True)
self.setSelectionMode(
QtWidgets.QAbstractItemView.ExtendedSelection
)
def add_widget(self, widget=None, index=-1):
item = QtWidgets.QListWidgetItem()
item.setSizeHint(widget.sizeHint())
if index < 0:
self.addItem(item)
else:
self.insertItem(index, item)
self.setItemWidget(item, widget)
def add_btn(self, txt='', index=-1):
if not txt or not isinstance(txt, basestring):
btn_name = 'Button Item {:02d}'.format(self.count() + 1)
else:
btn_name = txt
# widget = ReorderListAdd(btn_name) # ---
widget = QtWidgets.QPushButton(btn_name) # +++
widget.setIcon(QtGui.QIcon("Ok.png")) # +++
widget.clicked.connect(self.onClick) # +++
if index < 0:
self.add_widget(widget)
else:
self.add_widget(widget, index)
def dropEvent(self, event):
drop_index = self.indexAt(event.pos()).row()
if event.mimeData().hasText():
if event.mimeData().text() == 'ReorderListAdd()':
self.add_btn(index=drop_index)
super(ReorderList, self).dropEvent(event)
def dragEnterEvent(self, event):
event.accept()
def dragMoveEvent(self, event):
event.accept()
# +++
def onClick(self): # +++
print(self.sender().text())
class MainView(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.listWidget = ReorderList()
self.listWidget.addItems(["Item 1 1 1 ", "Item 22 22", "Item 3 33 333", ])
self.button = DragButton()
self.button.setText("Button")
self.button.setIcon(QtGui.QIcon("Ok.png"))
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.listWidget)
layout.addWidget(self.button)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = MainView()
w.show()
sys.exit(app.exec_())