Python 3.x 单击按钮时,显示目录中的下一个图像

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

我正在尝试用Python创建一个程序,允许在MainWin中加载一个图像,然后通过单击“下一步”更改图像,从而在文件夹中显示下一个图像。当下一步到达文件夹中文件的末尾时,它应该跳转到文件夹的开头。我设法加载了图片,甚至用“下一步”更改了图片,但只更改了一次——如果我再次单击“下一步”,图片将不再更改。你知道为什么吗?谢谢

  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条件:文件列表是在目录的完整内容上生成的(它不知道对话框中使用的文件过滤器),因此您可能会得到子目录和无法识别的文件类型。