简体   繁体   English

PyQt:从QListWidget删除自定义窗口小部件

[英]PyQt: removing custom widgets from a QListWidget

I am loading in a picture into a QGraphicsScene then when you click on the photo it will place circles in the area that is clicked. 我正在将图片加载到QGraphicsScene然后当您单击照片时,它将在所单击的区域中放置圆圈。 Then I am adding a custom widget that will keep a list of the points. 然后,我添加一个自定义小部件,该小部件将保留要点列表。 This widget has a couple of buttons. 这个小部件有几个按钮。 one of them will be able to move the circle and the other will be to delete it. 其中一个可以移动圆,另一个可以删除圆。 I am currently stuck on the delete part. 我目前停留在删除部分。

Problem 问题

I can delete the circle just fine and I can delete the widget from the list. 我可以删除圆圈,也可以从列表中删除小部件。 The problem is there is still a space in the list from where the widget once was and since I'm using the button from the widget and not selecting the item I'm not sure how to delete that spot. 问题在于列表中仍然有一个小部件所在的位置,并且由于我使用的是小部件中的按钮并且未选择该项目,因此我不确定如何删除该位置。 Also if I delete a bunch and then try and add some Python its self will crash and I have no idea why. 另外,如果我删除一堆然后尝试添加一些Python,它的自身将会崩溃,我也不知道为什么。

I'm not sure if what I want can be done since there really is no reference or if I'm better off moving the buttons to the main window and removing them from the custom widget. 我不确定是否可以做我想做的事情,因为实际上没有参考,或者我最好将按钮移至主窗口并将其从自定义小部件中删除。 If it is possible I would like to keep it the way I have it. 如果可能的话,我想保持原样。

There are a few files so I will put it on GitHub so I am not to take up a ton of space. 有一些文件,所以我将其放在GitHub上,因此我不会占用大量空间。 Any help is much appreciated. 任何帮助深表感谢。

GitHub Link GitHub链接

Link to GitHub Project 链接到GitHub Project

The relevant code (from Main.py ): 相关代码(来自Main.py ):

class MainWindow(QMainWindow, Ui_MainWindow):
    ...

    def Add_History(self,pos):
        self.HistoryWidget = HistoryList()
        self.HistoryWidget.setObjectName("HistoryWidget_"+ str(Constents.analysisCount))
        myQListWidgetItem = QListWidgetItem(self.History_List)
        myQListWidgetItem.setSizeHint(self.HistoryWidget.sizeHint())
        self.History_List.addItem(myQListWidgetItem)
        self.History_List.setItemWidget(myQListWidgetItem, self.HistoryWidget)
        self.HistoryWidget.buttonPushed.connect(self.deleteObject)
        self.HistoryWidget.setXpoint(str(pos.x()))
        self.HistoryWidget.setYpoint(str(pos.y()))
        self.HistoryWidget.setHistoryName("Point "+ str(Constents.analysisCount))
        Constents.analysisCount = Constents.analysisCount + 1

    def deleteObject(self):
        sender = self.sender() #var of object that sent the request
        row_number = sender.objectName().split("_")
        number = row_number[1]
        x,y = Constents.analysisDetails[str(number)]# getting xy for object
        self.loadPicture.findAndRemoveAnalysisPoint(x,y) #calling the class with the scense to delete it
        Constents.analysisDetails.pop(str(number)) # get rid of the object in the variables
        HistoryWidget = self.findChildren(HistoryList, "HistoryWidget_"+number)[0] #find the actual object

        HistoryWidget.deleteLater() #delete that object
        #Simport pdb; pdb.set_trace()
        #self.History_List.takeItem(HistoryWidget)

Pictures 图片

python崩溃的图片

在此处输入图片说明

You must delete both the item-widget and the item itself. 您必须同时删除item-widget和item本身。 To do that, a method is required for getting an item from an item-widget (or one of its child widgets). 为此,需要一种从item-widget(或其子小部件之一)中获取项目的方法。 A clean way to do this is to use the list-widget's itemAt method, which can get an item from a point on the screen. 一种干净的方法是使用列表小部件的itemAt方法,该方法可以从屏幕上的某个点获取项目。 The major benefit of doing it this way is that it does not require knowledge of the item's index, which can of course change when other items are deleted. 这样做的主要好处是它不需要了解项目的索引,而当删除其他项目时,当然可以改变。 It also means the item-widgets don't need to know anything about the specific list-widget items they are associated with. 这也意味着item-widget不需要了解与它们关联的特定list-widget项的任何信息。

Here is a re-write of your deleteObject method, which implements that: 这是您的deleteObject方法的deleteObject ,该方法实现了:

def deleteObject(self):
    sender = self.sender() #var of object that sent the request
    row_number = sender.objectName().split("_")
    number = row_number[1]
    x,y = Constents.analysisDetails[str(number)]# getting xy for object
    self.loadPicture.findAndRemoveAnalysisPoint(x,y) #calling the class with the scense to delete it
    Constents.analysisDetails.pop(str(number)) # get rid of the object in the variables

    # get the viewport coords of the item-widget
    pos = self.History_List.viewport().mapFromGlobal(
        sender.mapToGlobal(QtCore.QPoint(1, 1)))
    if not pos.isNull():
        # get the item from the coords
        item = self.History_List.itemAt(pos)
        if item is not None:
            # delete both the widget and the item
            widget = self.History_List.itemWidget(item)
            self.History_List.removeItemWidget(item)
            self.History_List.takeItem(self.History_List.row(item))
            widget.deleteLater()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM