class _BrowseWidget(QWidget): pathChanged = Signal(str) def __init__(self, parent=None): QWidget.__init__(self, parent) # Variables self._basedir = None # Widgets self._txt_path = QLineEdit() self._txt_path.setReadOnly(True) btn_browse = QPushButton("Browse") # Layouts layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self._txt_path, 1) layout.addWidget(btn_browse) self.setLayout(layout) # Signal btn_browse.released.connect(self._onBrowse) def _showDialog(self, basedir): raise NotImplementedError def _validatePath(self, path): raise NotImplementedError def _onBrowse(self): oldpath = self.path() newpath = self._showDialog(self.baseDir()) if not newpath and not oldpath: return elif not newpath and oldpath: newpath = oldpath else: self.pathChanged.emit(newpath) try: self.setPath(newpath) except Exception as ex: messagebox.exception(self, ex) def setBaseDir(self, path): if not path: path = os.getcwd() if os.path.isfile(path): path = os.path.dirname(path) if not os.path.isdir(path): raise ValueError("%s is not a directory" % path) self._basedir = path def baseDir(self): return self._basedir or os.getcwd() def setPath(self, path, update_basedir=True): if not path: self._txt_path.setText("") self.pathChanged.emit(None) return path = os.path.abspath(path) self._validatePath(path) self._txt_path.setText(path) self._txt_path.setCursorPosition(0) if update_basedir: self.setBaseDir(path) os.chdir(self.baseDir()) self.pathChanged.emit(path) def path(self): """ Returns the path to the selected file. If no file is selected, the method returns ``None`` """ path = self._txt_path.text() return path if path else None