Python 3.x 单击按钮时,显示目录中的下一个图像
我正在尝试用Python创建一个程序,允许在MainWin中加载一个图像,然后通过单击“下一步”更改图像,从而在文件夹中显示下一个图像。当下一步到达文件夹中文件的末尾时,它应该跳转到文件夹的开头。我设法加载了图片,甚至用“下一步”更改了图片,但只更改了一次——如果我再次单击“下一步”,图片将不再更改。你知道为什么吗?谢谢Python 3.x 单击按钮时,显示目录中的下一个图像,python-3.x,click,pyqt5,itertools,Python 3.x,Click,Pyqt5,Itertools,我正在尝试用Python创建一个程序,允许在MainWin中加载一个图像,然后通过单击“下一步”更改图像,从而在文件夹中显示下一个图像。当下一步到达文件夹中文件的末尾时,它应该跳转到文件夹的开头。我设法加载了图片,甚至用“下一步”更改了图片,但只更改了一次——如果我再次单击“下一步”,图片将不再更改。你知道为什么吗?谢谢 self.LoadImage.clicked.connect(self.LoadImg) self.NextImage.clicked.connect(self.Nex
self.LoadImage.clicked.connect(self.LoadImg)
self.NextImage.clicked.connect(self.NextImg)
def LoadImg(self):
global directory
global filename
directory = 'C:/Users/mario/Desktop/desktop 17112019 2/New Folder'
filename, _ = QtWidgets.QFileDialog.getOpenFileName(None, 'Select Image', directory, 'Image Files (*.png *.jpg *.jpeg)')
if filename: # If the user gives a file
pixmap = QtGui.QPixmap(filename) # Setup pixmap with the provided image
pixmap = pixmap.scaled(self.label.width(), self.label.height(),
QtCore.Qt.KeepAspectRatio) # Scale pixmap
self.label.setPixmap(pixmap) # Set the pixmap onto the label
self.label.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center
def vec(self):
a = os.listdir(directory)
k = a.index(os.path.basename(filename))
imageList = a[k:] + a[:k]
return imageList
def NextImg(self):
pool = itertools.cycle(self.vec())
print(next(pool))
pixmap = QtGui.QPixmap(directory + '/' + next(pool)) # Setup pixmap with the provided image
pixmap = pixmap.scaled(self.label.width(), self.label.height(), QtCore.Qt.KeepAspectRatio)
self.label.setPixmap(pixmap) # Set the pixmap onto the label
self.label.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center
编辑:我怀疑我需要用LoadImage和cycle iterator断开所选文件之间的连接,但不知道如何断开 首先,你不应该使用globals,尤其是敏感和“通用”名称,如
目录
。我还建议您不要对函数和变量使用大写的名称
要跟踪当前文件并循环浏览目录的内容,请改用class属性
在本例中,我从所选文件目录的内容开始使用python迭代器,每次按下“next”(下一步)按钮,迭代器的下一项都会被加载,如果迭代器已经结束,它将生成一个新项
from PyQt5 import QtCore, QtGui, QtWidgets
class ImageLoader(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
layout = QtWidgets.QGridLayout(self)
self.label = QtWidgets.QLabel()
layout.addWidget(self.label, 0, 0, 1, 2)
self.label.setMinimumSize(200, 200)
# the label alignment property is always maintained even when the contents
# change, so there is no need to set it each time
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.loadImageButton = QtWidgets.QPushButton('Load image')
layout.addWidget(self.loadImageButton, 1, 0)
self.nextImageButton = QtWidgets.QPushButton('Next image')
layout.addWidget(self.nextImageButton)
self.loadImageButton.clicked.connect(self.loadImage)
self.nextImageButton.clicked.connect(self.nextImage)
self.dirIterator = None
self.fileList = []
def loadImage(self):
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
self, 'Select Image', '', 'Image Files (*.png *.jpg *.jpeg)')
if filename:
pixmap = QtGui.QPixmap(filename).scaled(self.label.size(),
QtCore.Qt.KeepAspectRatio)
if pixmap.isNull():
return
self.label.setPixmap(pixmap)
dirpath = os.path.dirname(filename)
self.fileList = []
for f in os.listdir(dirpath):
fpath = os.path.join(dirpath, f)
if os.path.isfile(fpath) and f.endswith(('.png', '.jpg', '.jpeg')):
self.fileList.append(fpath)
self.fileList.sort()
self.dirIterator = iter(self.fileList)
while True:
# cycle through the iterator until the current file is found
if next(self.dirIterator) == filename:
break
def nextImage(self):
# ensure that the file list has not been cleared due to missing files
if self.fileList:
try:
filename = next(self.dirIterator)
pixmap = QtGui.QPixmap(filename).scaled(self.label.size(),
QtCore.Qt.KeepAspectRatio)
if pixmap.isNull():
# the file is not a valid image, remove it from the list
# and try to load the next one
self.fileList.remove(filename)
self.nextImage()
else:
self.label.setPixmap(pixmap)
except:
# the iterator has finished, restart it
self.dirIterator = iter(self.fileList)
self.nextImage()
else:
# no file list found, load an image
self.loadImage()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
imageLoader = ImageLoader()
imageLoader.show()
sys.exit(app.exec_())
@mavish你能解释一下“不正确”是什么意思吗?fpath变量存储了不正确的路径C:/Users\address.jpg,所以我用fpath=dirpath+'/'+f替换了它。我还设想,如果os.path.isfile(fpath)和f.endswith((“.png”、“.jpg”、“.jpeg”):真的没有必要,因为用户只能单击显示的文件,这些文件是“图像文件(*.png*.jpg*.jpeg)”)(我还添加了*.JPG,因为我的一些图片有这个扩展名。谢谢你的回复!这是因为Qt和python在windows上管理文件路径的方式不同(使用恼人的反斜杠而不是标准斜杠)。我建议你使用
os.sep.join((dirpath,f))
对于这些情况,需要使用if条件:文件列表是在目录的完整内容上生成的(它不知道对话框中使用的文件过滤器),因此您可能会得到子目录和无法识别的文件类型。