1

I need to select the default file that appears in a combobox from a directory listing of files. With a normal combobox, it is easy enough to find the index of the value you want using .findText, but this does not appear to work for QFileSystemModel comboboxes, possibly due to the way the list of options does not populate until the directory listing can be resourced.

Here is what I have tried:

import sys
import collections
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QLabel, QGridLayout, QWidget, QComboBox
from PyQt5.QtCore import QSize, QRect    

class ComboWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.setMinimumSize(QSize(640, 140))    
        self.setWindowTitle("Combobox example") 

        centralWidget = QWidget(self)          
        self.setCentralWidget(centralWidget)   

        # Create combobox and add items.
        self.fsm = QtWidgets.QFileSystemModel()        
        self.fsm.setNameFilters(["*.txt"]) 
        self.configComboBox = QtWidgets.QComboBox(self)
        self.configComboBox.setGeometry(QRect(40, 40, 491, 31))
        self.configComboBox.setObjectName(("comboBox"))
        self.configComboBox.setModel(self.fsm)                
        self.fsm.setFilter(QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Files)        
        # "text_files" is a subdir of current dir with files 
        # example1.txt, example2.txt, example3.txt
        self.configComboBox.setRootModelIndex(self.fsm.setRootPath("text_files")) 
        # V V This section does not work V V
        index = self.configComboBox.findText(MainConfig.settings["default_txt_file"])
        self.configComboBox.setCurrentIndex(index)

class MainConfig:
    settings = collections.OrderedDict()  

    @staticmethod
    def createDefaultConfig(name):
        MainConfig.settings["default_txt_file"] = "example3.txt"     

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    mainWin = ComboWindow()
    mainWin.show()
    sys.exit( app.exec_() )
eyllanesc
  • 235,170
  • 19
  • 170
  • 241

1 Answers1

2

As I indicated in this answer, the QFileSystemModel is loaded asynchronously in a new thread so you must use the directoryLoaded signal to know when the information is finished loading:

import collections
import os
import sys

from PyQt5.QtWidgets import (
    QApplication,
    QComboBox,
    QFileSystemModel,
    QMainWindow,
    QWidget,
)
from PyQt5.QtCore import pyqtSlot, QDir, QRect, QSize


class ComboWindow(QMainWindow):
    def __init__(self, parent=None):
        super(ComboWindow, self).__init__(parent=None)

        self.setMinimumSize(QSize(640, 140))
        self.setWindowTitle("Combobox example")

        centralWidget = QWidget(self)
        self.setCentralWidget(centralWidget)

        # Create combobox and add items.
        self.fsm = QFileSystemModel()
        self.fsm.setNameFilters(["*.txt"])
        self.configComboBox = QComboBox(self)
        self.configComboBox.setGeometry(QRect(40, 40, 491, 31))
        self.configComboBox.setObjectName(("comboBox"))
        self.configComboBox.setModel(self.fsm)
        self.fsm.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.fsm.directoryLoaded.connect(self.on_directoryLoaded)
        current_dir = os.path.dirname(os.path.realpath(__file__))
        dir_path = os.path.join(current_dir, "text_files")
        self.configComboBox.setRootModelIndex(self.fsm.setRootPath(dir_path))

    @pyqtSlot(str)
    def on_directoryLoaded(self, path):
        index = self.configComboBox.findText(MainConfig.settings["default_txt_file"])
        self.configComboBox.setCurrentIndex(index)


class MainConfig:
    settings = collections.OrderedDict()

    @staticmethod
    def createDefaultConfig(name):
        MainConfig.settings["default_txt_file"] = name


if __name__ == "__main__":
    MainConfig.createDefaultConfig("example3.txt")
    app = QApplication(sys.argv)
    mainWin = ComboWindow()
    mainWin.show()
    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241