简体   繁体   中英

Dynamic highlighting of files in pyqt5

I am trying to make sort of file browser for images

图片

It opens images when i press buttons next ot previous and shows list of files in mentioned directory. However,it highlights files on listview only with clicking by mouse.

How can i highlight the curent file in listview area(on the left) while i am pressing the button(next or previous)?

here is my code:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import QColor,QTextCharFormat
import os


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        self.filename=[]
        self.path=[]
        self.current_im=[]
        Dialog.setObjectName("Dialog")
        Dialog.resize(832, 586)
        self.toolButton = QtWidgets.QToolButton(Dialog)
        self.toolButton.setGeometry(QtCore.QRect(90, 70, 25, 19))
        self.toolButton.setPopupMode(QtWidgets.QToolButton.DelayedPopup)
        self.toolButton.setObjectName("toolButton")

        self.label = QtWidgets.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(20, 70, 81, 16))
        self.label.setObjectName("label")

        #self.lbl = QLabel(self)
        self.qle = QLineEdit(Dialog)
        self.qle.setGeometry(QtCore.QRect(120, 20, 191, 16))
        self.t=self.qle.textChanged[str]
        self.qle.textChanged[str].connect(self.onChanged)

        #self.lbl.move(60, 40)

        self.label_2 = QtWidgets.QLabel(Dialog)
        self.label_2.setGeometry(QtCore.QRect(10, 20, 91, 16))
        self.label_2.setObjectName("label_2")

        self.toolButton_2 = QtWidgets.QToolButton(Dialog)
        self.toolButton_2.setGeometry(QtCore.QRect(500, 20, 31, 19))
        self.toolButton_2.setObjectName("toolButton_2")

        self.checkBox = QtWidgets.QCheckBox(Dialog)
        self.checkBox.setGeometry(QtCore.QRect(730, 260, 91, 21))
        self.checkBox.setObjectName("checkBox")

        #self.scrollArea = QtWidgets.QScrollArea(Dialog)
        #self.scrollArea.setGeometry(QtCore.QRect(10, 110, 261, 461))
        #self.scrollArea.setWidgetResizable(True)
        #self.scrollArea.setObjectName("scrollArea")

        #self.scrollAreaWidgetContents = Widget(Dialog)
        #self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(10, 110, 261, 461))
        #self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")

        #self.verticalScrollBar = QtWidgets.QScrollBar(self.scrollAreaWidgetContents)
        #self.verticalScrollBar.setGeometry(QtCore.QRect(240, 0, 16, 451))
        #self.verticalScrollBar.setOrientation(QtCore.Qt.Vertical)
        #self.verticalScrollBar.setObjectName("verticalScrollBar")

        #self.scrollArea.setWidget(self.scrollAreaWidgetContents)

        #self.hlay = QHBoxLayout(Dialog)
        self.listview = QListView(Dialog)
        self.fileModel = QFileSystemModel(Dialog)
        #self.hlay.addWidget(self.listview)
        #self.hlay.setGeometry(QtCore.QRect(10, 110, 261, 461))
        self.listview.setGeometry(QtCore.QRect(10, 110, 261, 461))

        self.label_3 = QtWidgets.QLabel(Dialog)
        self.label_3.setGeometry(QtCore.QRect(290, 140, 401, 361))
        self.label_3.setText("")
        #self.label_3.setPixmap(QtGui.QPixmap("C:/Users/Nigel/Desktop/Waste_classification/Waste-Classification-master/dataset/train_set/1/2а (5).jpg"))
        #self.label_3.setScaledContents(True)
        self.label_3.setObjectName("label_3")

        self.comboBox = QtWidgets.QComboBox(Dialog)
        self.comboBox.setGeometry(QtCore.QRect(720, 140, 69, 22))
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")

        self.label_4 = QtWidgets.QLabel(Dialog)
        self.label_4.setGeometry(QtCore.QRect(720, 120, 51, 16))
        self.label_4.setObjectName("label_4")
        self.label_5 = QtWidgets.QLabel(Dialog)
        self.label_5.setGeometry(QtCore.QRect(390, 20, 91, 16))
        self.label_5.setObjectName("label_5")

        self.comboBox_2 = QtWidgets.QComboBox(Dialog)
        self.comboBox_2.setGeometry(QtCore.QRect(720, 210, 81, 22))
        self.comboBox_2.setObjectName("comboBox_2")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")

        self.label_6 = QtWidgets.QLabel(Dialog)
        self.label_6.setGeometry(QtCore.QRect(720, 190, 47, 13))
        self.label_6.setObjectName("label_6")

        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(290, 510, 81, 41))
        self.pushButton.setObjectName("pushButton")

        self.pushButton_2 = QtWidgets.QPushButton(Dialog)
        self.pushButton_2.setGeometry(QtCore.QRect(380, 510, 81, 41))
        self.pushButton_2.setObjectName("pushButton_2")

        self.pushButton_3 = QtWidgets.QPushButton(Dialog)
        self.pushButton_3.setGeometry(QtCore.QRect(470, 510, 81, 41))
        self.pushButton_3.setObjectName("pushButton_3")


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

    def onChanged(self, text):

        DB=text+'.csv'
        print()
        #self.lbl.adjustSize()-

            
    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))

        self.toolButton.setText(_translate("Dialog", "..."))
        self.label.setText(_translate("Dialog", "Images folder"))
        self.label_2.setText(_translate("Dialog", "Database filename:"))
        self.toolButton_2.setText(_translate("Dialog", "..."))

        self.checkBox.setText(_translate("Dialog", "Show Grid"))

        self.comboBox.setItemText(0, _translate("Dialog", "1A"))
        self.comboBox.setItemText(1, _translate("Dialog", "2A"))
        self.comboBox.setItemText(2, _translate("Dialog", "3A"))
        self.comboBox.setItemText(3, _translate("Dialog", "5A"))
        self.comboBox.setItemText(4, _translate("Dialog", "12A"))
        self.comboBox.setItemText(5, _translate("Dialog", "17A"))
        self.comboBox.setItemText(6, _translate("Dialog", "19A"))
        self.comboBox.setItemText(7, _translate("Dialog", "20A"))
        self.comboBox.setItemText(8, _translate("Dialog", "22A"))
        self.comboBox.setItemText(9, _translate("Dialog", "Unsorted"))

        self.label_4.setText(_translate("Dialog", "Class:"))
        #self.label_4.setBackground(QColor('yellow'))
        self.label_5.setText(_translate("Dialog", "Database location:"))

        self.comboBox_2.setItemText(0, _translate("Dialog", "600x500"))
        self.comboBox_2.setItemText(1, _translate("Dialog", "800x500"))
        self.comboBox_2.setItemText(2, _translate("Dialog", "1500x500"))

        self.label_6.setText(_translate("Dialog", "Grid size:"))
        self.pushButton.setText(_translate("Dialog", "Previous"))
        self.pushButton_2.setText(_translate("Dialog", "Next"))
        self.pushButton_3.setText(_translate("Dialog", "Add to DB"))
        self.toolButton.clicked.connect(self.open_dialog_box)
        self.pushButton_2.clicked.connect(self.next_im)
        self.pushButton.clicked.connect(self.previous_im)


        #self.toolButton.clicked.connect()
        #self.toolButton_2.clicked.connect(self.open_dialog_box)




    def open_dialog_box(self):
        self.filename=QFileDialog.getExistingDirectory()

        self.fileModel.setRootPath(self.filename)
        self.listview.setModel(self.fileModel)
        self.listview.setRootIndex(self.fileModel.index(self.filename))
        #selection_model = self.listview.selectionModel()
        #index = self.fileModel.index(0, 0)
        #print(index)
        #selection_model.select(index, QtGui.QItemSelectionModel.Select)
        self.listview.clicked.connect(self.on_clicked)
        

    def on_clicked(self, index):
        #index = self.fileModel.index(0,0)
        #print(index)
        self.path = self.fileModel.fileInfo(index).absoluteFilePath()
        print(index)
        self.label_3.setPixmap(QtGui.QPixmap(self.path))
        self.label_3.setScaledContents(True)
        self.current_im=self.path


    def on_clicked_1(self):
        self.path = self.current_im
        #print(path)
        self.label_3.setPixmap(QtGui.QPixmap(self.path))
        self.label_3.setScaledContents(True)


    def next_im(self):
        directory=self.filename
        list_1=[]
        if directory==[] or self.current_im==[]:
            pass
        else:

            for f in os.listdir(directory):
                fpath = directory+'/'+f
                list_1.append(fpath)

            #print(list_1)

            n=list_1.index(self.current_im)

            if n==(len(list_1)-1):
                k=0
            else:
                k=n+1


            self.current_im=list_1[k]

            self.on_clicked_1()

            #self.label_3.setPixmap(QtGui.QPixmap(self.current_im))
            #self.label_3.setScaledContents(True)

    def previous_im(self):
        directory=self.filename
        list_1=[]
        if directory==[] or self.current_im==[]:
            pass
        else:
            for f in os.listdir(directory):
                fpath = directory+'/'+f
                list_1.append(fpath)

            #print(list_1)

            n=list_1.index(self.current_im)

            self.current_im=list_1[n-1]
            self.label_3.setPixmap(QtGui.QPixmap(self.current_im))
            self.label_3.setScaledContents(True)

    


        
    







if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()

    #w = Widget()
    #w.show()
    sys.exit(app.exec_())

First of all, you should not modify the code generated by Qt Designer, so I have taken the time to create the.ui, also I have used layouts for a better handling of the geometry.

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>724</width>
    <height>463</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <layout class="QGridLayout" name="gridLayout" rowstretch="0,0,1,0" columnstretch="1,0,0">
   <item row="0" column="0" colspan="3">
    <layout class="QHBoxLayout" name="horizontalLayout_3">
     <item>
      <widget class="QLabel" name="label">
       <property name="text">
        <string>Database filename:</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QLineEdit" name="lineEdit"/>
     </item>
     <item>
      <widget class="QLabel" name="label_2">
       <property name="text">
        <string>Database location:</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QToolButton" name="toolButton_2">
       <property name="text">
        <string>...</string>
       </property>
      </widget>
     </item>
     <item>
      <spacer name="horizontalSpacer_3">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
    </layout>
   </item>
   <item row="1" column="0">
    <layout class="QHBoxLayout" name="horizontalLayout">
     <item>
      <widget class="QLabel" name="label_3">
       <property name="text">
        <string>Images folder</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QToolButton" name="select_folder_button">
       <property name="text">
        <string>...</string>
       </property>
      </widget>
     </item>
     <item>
      <spacer name="horizontalSpacer">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
    </layout>
   </item>
   <item row="1" column="1">
    <spacer name="verticalSpacer_2">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>28</height>
      </size>
     </property>
    </spacer>
   </item>
   <item row="1" column="2">
    <spacer name="verticalSpacer_3">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>28</height>
      </size>
     </property>
    </spacer>
   </item>
   <item row="2" column="0">
    <widget class="QListView" name="listview"/>
   </item>
   <item row="2" column="1">
    <widget class="QLabel" name="image_label">
     <property name="styleSheet">
      <string notr="true">background-color: rgb(255, 255, 255);</string>
     </property>
     <property name="text">
      <string/>
     </property>
     <property name="scaledContents">
      <bool>true</bool>
     </property>
     <property name="alignment">
      <set>Qt::AlignCenter</set>
     </property>
    </widget>
   </item>
   <item row="2" column="2">
    <layout class="QVBoxLayout" name="verticalLayout">
     <item>
      <widget class="QLabel" name="label_5">
       <property name="text">
        <string>Class:</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QComboBox" name="comboBox"/>
     </item>
     <item>
      <widget class="QLabel" name="label_6">
       <property name="text">
        <string>Grid Size</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QComboBox" name="comboBox_2"/>
     </item>
     <item>
      <widget class="QCheckBox" name="checkBox">
       <property name="text">
        <string>Show Grid</string>
       </property>
      </widget>
     </item>
     <item>
      <spacer name="verticalSpacer">
       <property name="orientation">
        <enum>Qt::Vertical</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>20</width>
         <height>40</height>
        </size>
       </property>
      </spacer>
     </item>
    </layout>
   </item>
   <item row="3" column="0">
    <spacer name="verticalSpacer_6">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>39</height>
      </size>
     </property>
    </spacer>
   </item>
   <item row="3" column="1">
    <layout class="QHBoxLayout" name="horizontalLayout_2">
     <item>
      <widget class="QPushButton" name="previous_button">
       <property name="minimumSize">
        <size>
         <width>80</width>
         <height>40</height>
        </size>
       </property>
       <property name="text">
        <string>Previous</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="next_button">
       <property name="minimumSize">
        <size>
         <width>80</width>
         <height>40</height>
        </size>
       </property>
       <property name="text">
        <string>Next</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="pushButton_3">
       <property name="minimumSize">
        <size>
         <width>80</width>
         <height>40</height>
        </size>
       </property>
       <property name="text">
        <string>Add to DB</string>
       </property>
      </widget>
     </item>
     <item>
      <spacer name="horizontalSpacer_2">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
    </layout>
   </item>
   <item row="3" column="2">
    <spacer name="verticalSpacer_5">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>39</height>
      </size>
     </property>
    </spacer>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

You must convert the.ui to.py:

pyuic5 gui.ui -o gui.py -x

Now to the problem, the logic is to centralize the image change process in only one method, as in this case everything focuses on the selection of an item associated with a QModelIndex, so every time the selected item changes then the image must be updated, and the buttons will only change the selected item:

from PyQt5 import QtCore, QtGui, QtWidgets

from gui import Ui_Dialog


class Dialog(QtWidgets.QDialog, Ui_Dialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.filemodel = QtWidgets.QFileSystemModel(self)
        self.listview.setModel(self.filemodel)
        self.select_folder_button.clicked.connect(self.select_folder)
        self.listview.selectionModel().currentChanged.connect(self.update_image)
        self.next_button.clicked.connect(self.next_image)
        self.previous_button.clicked.connect(self.previous_image)
        self.image_label.setFixedSize(400, 360)

    @QtCore.pyqtSlot()
    def select_folder(self):
        dirname = QtWidgets.QFileDialog.getExistingDirectory()
        if dirname:
            self.filemodel.setRootPath(dirname)
            self.listview.setRootIndex(self.filemodel.index(dirname))

    @QtCore.pyqtSlot()
    def next_image(self):
        index = self.listview.moveCursor(
            QtWidgets.QAbstractItemView.MoveNext, QtCore.Qt.NoModifier
        )
        self.listview.selectionModel().setCurrentIndex(
            index, QtCore.QItemSelectionModel.SelectCurrent
        )

    @QtCore.pyqtSlot()
    def previous_image(self):
        index = self.listview.moveCursor(
            QtWidgets.QAbstractItemView.MovePrevious, QtCore.Qt.NoModifier
        )
        self.listview.selectionModel().setCurrentIndex(
            index, QtCore.QItemSelectionModel.SelectCurrent
        )

    def update_image(self, index):
        fileinfo = self.filemodel.fileInfo(index)
        if fileinfo and fileinfo.isFile():
            filename = fileinfo.absoluteFilePath()
            self.image_label.setPixmap(QtGui.QPixmap(filename))


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Dialog()
    w.show()
    sys.exit(app.exec_())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM