如何解决有没有办法停止为 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()
我的应用程序还没有掉线:
正如您从第二张图片中看到的,每当我单击或悬停等时,我的数据函数都由视图运行。
解决方法
每次视图重新绘制自身时(例如,当您滚动它时),它会从模型中获取所有必要的数据,这就是设计的工作方式,我认为干扰这个过程不是一个好主意。如果遇到延迟,您可以优化模型,例如 - 使用 dict {path: QImage}
(或更好的事件 {ext: QImage}
)缓存装饰角色的图像,如果缓存不包含条目,则仅调用 get_icon
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。