微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有没有办法停止为 PyQt ListView 发出信号?

如何解决有没有办法停止为 PyQt ListView 发出信号?

我正在尝试构建一个正在转换文件格式的 PyQt GUI 应用程序。我有一个 ListView,它连接到我的 QAbstractListModel。

我的问题是,作为 MVC 设计的初学者,我理解每当我悬停光标、聚焦应用程序窗口等时,我的视图都会发出信号,并且 ListView 访问我的模型的 data() 方法,然后重复图标的整个过程设置和其他东西。

除了 drop 事件之外,有没有办法停止为我的列表视图发出信号?

因为我不需要为悬停、焦点信号等更新我的视图。

我尝试将 blockSignals (True) 用于视图,但它也阻止了我不想阻止的丢弃信号。但我不确定我是否正确实施了它。我在模型的 init 方法添加了 blockSingals。

这是我的模型:

class FileModel(QtCore.QAbstractListModel):
    
    def __init__(self,data = [],parent = None):
        QtCore.QAbstractListModel.__init__(self,parent)
        self._data = data

        
    def rowCount(self,parent):
         return len(self._data) 
    
    def data(self,index,role):

# Here I print the role to show you
# my view check my model for every signal

        print(role)  
        if role == QtCore.Qt.displayRole:
            
            row = index.row()
            value = self._data[row]  

            
            return value
        
        if role == QtCore.Qt.decorationRole:
            row = index.row()
            path = self._data[row].replace("/","\\")
            image = self.get_icon(path,"small")
            qtimage = ImageQt.ImageQt(image)
            pixmap = QtGui.Qpixmap.fromImage(qtimage)
            icon = QtGui.QIcon(pixmap)

            return icon        
    
    def insertRows(self,position,rows,items,parent):
        self.beginInsertRows(QtCore.QModelIndex(),position + rows - 1)

        for index in range(rows):
            self._data.insert(position,items[index])
            
        self.endInsertRows()
        
        return True
    
    def get_icon(self,PATH,size):  
        SHGFI_ICON = 0x000000100  
        SHGFI_ICONLOCATION = 0x000001000  
        if size == "small":  
            SHIL_SIZE= 0x00001  
        elif size == "large":  
            SHIL_SIZE= 0x00002  
        else:  
            raise TypeError("Invalid argument for 'size'. Must be equal to 'small' or 'large'")  

        ret,info = shell.SHGetFileInfo(PATH,SHGFI_ICONLOCATION | SHGFI_ICON | SHIL_SIZE)  
        hIcon,iIcon,dwAttr,name,typeName = info  
        ico_x = win32api.GetSystemMetrics(win32con.SM_CXICON)  
        hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))  
        hbmp = win32ui.CreateBitmap()  
        hbmp.CreateCompatibleBitmap(hdc,ico_x,ico_x)  
        hdc = hdc.CreateCompatibleDC()  
        hdc.SelectObject(hbmp)  
        hdc.DrawIcon((0,0),hIcon)  
        win32gui.DestroyIcon(hIcon)  

        bmpinfo = hbmp.GetInfo()  
        bmpstr = hbmp.GetBitmapBits(True)  
        img = Image.frombuffer(  
            "RGBA",(bmpinfo["bmWidth"],bmpinfo["bmHeight"]),bmpstr,"raw","BGRA",1  
        )  

        if size == "small":  
            img = img.resize((20,20),Image.ANTIALIAS)  

        return img

这是我的用户界面:

class Ui_Window(object):
    def setupUi(self,MainWindow):
        MainWindow.setobjectName("MainWindow")
        MainWindow.resize(800,600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setobjectName("centralwidget")
        self.listView = FileView(MainWindow)
        self.listView.setGeometry(QtCore.QRect(35,21,721,521))
        self.listView.setobjectName("listView")
        self.listView.setviewmode(QtWidgets.QListWidget.ListMode)


        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self,MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setwindowTitle(_translate("MainWindow","MainWindow"))



class FileView(Ui_Window,QListView): 
    def __init__(self,parent=None):
        super().__init__(parent)
        self.setAcceptDrops(True)
        self.setDragDropMode(QAbstractItemView.DragDrop)
        self.items = []
        self.model = FileModel(self.items)
        self.setModel(self.model)

        
    def setupUi(self,Form):
       super().setupUi(Form)

        
    def dragenterEvent(self,event):
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()

    def dragMoveEvent(self,event):
        if event.mimeData().hasUrls():
            event.setDropAction(Qt.copyAction)
            event.accept()
        else:
            event.ignore()

    def dropEvent(self,event):
        if event.mimeData().hasUrls():
            event.setDropAction(Qt.copyAction)
            event.accept()

            links = []

            for url in event.mimeData().urls():
                if url.isLocalFile():
                    links.append(str(url.toLocalFile()))
                else:
                    links.append(str(url.toString()))
                        
            self.model.insertRows(0,len(links),links,QtCore.QModelIndex())
        

            
        else:
            event.ignore()    

我的应用程序还没有掉线:

My application nothing dropped yet

在这里,我放下了一个文件并将鼠标悬停在文件上几次:

Here I dropped a file and hovered my mouse on the file couple of times

正如您从第二张图片中看到的,每当我单击或悬停等时,我的数据函数都由视图运行。

解决方法

每次视图重新绘制自身时(例如,当您滚动它时),它会从模型中获取所有必要的数据,这就是设计的工作方式,我认为干扰这个过程不是一个好主意。如果遇到延迟,您可以优化模型,例如 - 使用 dict {path: QImage}(或更好的事件 {ext: QImage})缓存装饰角色的图像,如果缓存不包含条目,则仅调用 get_icon

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。