在PyQt中配置自定义滚动条

0 投票
1 回答
2324 浏览
提问于 2025-04-16 18:43

我正在用PyQt构建一个图像处理的图形用户界面(GUI)。我需要实现的一个功能是使用滚动条来浏览一个图像文件夹。具体来说,如果在/my/dir文件夹里有1000张图片,我希望滚动条的移动距离能对应到图片的编号(从1到1000)。也就是说,滚动条最左边对应的是图片1,最右边对应的是图片1000。如果滚动条在左边到右边的33%位置,那么显示的图片编号就是round(0.33333*1000) = 333。

现在我已经有了一套可以正常工作的控件,能够从文件夹中显示一张图片,并且有“下一张”和“上一张”按钮,可以用来前后浏览。这个软件的目的是为了通过深度的人类标注进行监督学习,所以需要快速浏览大量没有明显变化的图片。这就是我需要滑块条的原因。

如果滚动条的信号和槽的工作方式和按钮一样,我相信我可以通过一些技巧来让它操作图像名称并更新显示的图片。不过,我需要的帮助是一些基本的语法,解释如何创建一个滚动条类,并把它放在我的图像下方,使用QGridLayout布局。


我通过搜索和尝试找到的一个答案如下。

我找到的另一个解决方案接口很好,虽然我更喜欢@Stephen Terry的建议,直接遍历文件本身。我的解决方案是基于这里的教程代码:http://zetcode.com/tutorials/pyqt4/widgets/

我首先创建了一个自己的小类:

class InterpolatingScrollBar(QtGui.QWidget):

    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.testbar = QtGui.QSlider(QtCore.Qt.Horizontal,self)
        self.testbar.setGeometry(10,10,500,30)
        self.testbar.setFocusPolicy(QtCore.Qt.NoFocus)

然后在主控制类中创建了这个类的一个实例,

    self.scrollbar = buttonUtils.InterpolatingScrollBar()
    self.scrollbar.testbar.setMinimum(self.overall_counter)
    self.scrollbar.testbar.setMaximum(self.max_image_num)

其中max_image_num是通过类似的glob()调用计算出来的,检查目录中哪些是jpg格式的图片。接着我用这段代码连接到滚动条的“值改变”信号:

    self.connect(self.scrollbar.testbar,QtCore.SIGNAL('valueChanged(int)'),self.getScrollValue)

def getScrollValue(self,value):
        self.overall_counter = value
        self.pb1.previousSlot(self.overall_counter)
        self.nb1.nextSlot(self.overall_counter)
        self.pixmap = QtGui.QPixmap(self.directory_name + self.pb1.new_image_str)
        self.label.setPixmap(self.pixmap)

其中pb1和nb1分别是“上一张按钮”和“下一张按钮”,它们有相应的功能来更新按钮上显示的计数,以及指向新显示图片的字符串名称。

1 个回答

1

最简单的方法就是使用一个叫做 QListWidget 的工具,把你的图片放进去,作为 QListWidgetItem 的图标。举个例子,代码可以写成这样:

self.list_widget = QListWidget()
files = glob.glob('YourDirectory/*.jpg') #Get all jpegs in your directory
for i in files:
    self.list_widget.addItem(QListWidgetItem(QIcon(i),'your text here'))
self.list_widget.setIconSize(QSize(400,300)) #Set your image size

这样做的话,你就能得到接近你想要的滚动条效果;用户可以同时看到不止一张图片,除非你把图片做得很大,填满整个屏幕。希望你能根据自己的需求进行调整。

撰写回答