简体   繁体   中英

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. 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.

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. Any help is much appreciated.

GitHub Link

Link to GitHub Project

The relevant code (from 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. To do that, a method is required for getting an item from an item-widget (or one of its child widgets). 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. 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.

Here is a re-write of your deleteObject method, which implements that:

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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