问题描述
我正在pyqt5中创建拖放GUI,并尝试获取拖放操作的目标小部件,但是当我尝试QDrag对象的target()函数时,我返回了 main strong> .MainWindow对象位于0x0000025FDAC09EE0>,我不知道该如何使用。我想访问qgridLayout中的小部件的索引,以便可以使两个小部件交换位置。
这是我的代码:
import sys
from PyQt5.QtCore import Qt,QMimeData
from PyQt5.QtGui import QDrag
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QPushButton,QWidget,QApplication,qgridLayout,QScrollArea,QMainWindow,QSlider
class Stroj:
def __init__(self,rok,naziv,trajanje):
self.rok = rok
self.naziv = naziv
self.trajanje = trajanje
class Button(QPushButton):
drag = 0
def __init__(self,title,parent):
super().__init__(title,parent)
def mouseMoveEvent(self,e):
if e.buttons() != Qt.LeftButton:
return
mimeData = QMimeData()
mimeData.setText(self.text())
self.drag = QDrag(self)
self.drag.setMimeData(mimeData)
self.drag.setpixmap(self.grab())
self.drag.setHotSpot(self.rect().center())
dropAction = self.drag.exec_(Qt.MoveAction)
class MainWindow(QMainWindow):
layout = qgridLayout()
btns = []
snd = ""
i = 0
j = 0
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setAcceptDrops(True)
self.scroll = QScrollArea()
self.widget = QWidget()
self.drag = QDrag(self)
SL = []
for x in range(30):
self.btns.append(x)
for x in range(30):
self.btns[x] = Button(str(x),self)
self.btns[x].setSizePolicy(QtWidgets.QSizePolicy.Minimum,QtWidgets.QSizePolicy.Minimum)
self.layout.addWidget(self.btns[x],self.i,self.j)
if(self.j > 5):
self.j = 0
self.i += 1
else:
self.j += 1
self.widget.setLayout(self.layout)
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBaralwaysOn)
self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBaralwaysOn)
self.scroll.setWidgetResizable(True)
self.scroll.setWidget(self.widget)
self.setCentralWidget(self.scroll)
self.setwindowTitle('Raspored')
self.setGeometry(350,75,950,750)
def dragenterEvent(self,e):
self.snd = e.mimeData().text()
e.accept()
def dragMoveEvent(self,e):
e.accept()
def dropEvent(self,e):
sender = self.snd
position = e.pos()
position.setX(int(position.x() - self.btns[int(sender)].width() / 2))
position.setY(int(position.y() - self.btns[int(sender)].height() / 2))
self.btns[int(sender)].move(position)
print(self.layout.indexOf(e.source()))
print(e.source().drag.target())
e.setDropAction(Qt.MoveAction)
e.accept()
def main():
app = QApplication(sys.argv)
main = MainWindow()
main.show()
app.exec_()
if __name__ == '__main__':
main()
解决方法
放置事件的目标始终是接收放置动作的小部件,因此很明显,如果您从主窗口实例拦截事件,则将主窗口作为目标。
如果需要在特定位置找到小部件,则需要使用QApplication.widgetAt(pos)
。
在下面的示例中,从给定的代码进行了修改,仅当源是$ python3 -V
Python 3.7.0
实例且目标不相同时,我才接受dragEnter / dragMove事件。然后,我使用它们在布局中的位置切换这些按钮。
Button
考虑到这是一个非常简单的实现:您还应确保小部件实际上是同一窗口和的子代,并且它们在同一布局中。