class DockFolders(QDockWidget, Ui_dock_folders): def __init__(self, parent): QDockWidget.__init__(self, parent=parent) self.setupUi(self) self.mw = parent # self.ed_path.setText(self.mw.cfg.value("root_path", defaultValue=QDir.homePath())) self.setupDirModel() self.tree.clicked.connect(self.onDirClicked) # self.btn_selectdir.clicked.connect(self.onButtonSelectDir) self.ed_path.returnPressed.connect(self.setupDirModel) def setupDirModel(self): """ Show folders on tree view """ path = self.ed_path.text() self.dirModel = QFileSystemModel() self.dirModel.setRootPath(path) self.dirModel.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot) self.tree.setModel(self.dirModel) self.tree.setRootIndex(self.dirModel.index(path)) self.tree.hideColumn(1) self.tree.hideColumn(2) self.tree.hideColumn(3) self.tree.resizeColumnToContents(0) def onDirClicked(self, index): path = self.dirModel.fileInfo(index).absoluteFilePath() self.mw.loadAlbum(path)
class FolderContents(QWidget): def __init__(self, editor): super().__init__(editor) self.editor = editor self.layout = QHBoxLayout() self.setLayout(self.layout) self.tView = QTreeView() self.createFileExplorer() def createFileExplorer(self): self.dirModel = QFileSystemModel() # self.fileModel = QFileSystemModel() # self.fmDialog = QDialog() # self.dirModel.setFilter() self.root = self.dirModel.setRootPath(QDir.homePath()) self.dirModel.setFilter(QDir.NoDot | QDir.AllEntries) # self.dirModel.setFilter(QDir.AllDirs) self.tView.setModel(self.dirModel) self.layout.addWidget(self.tView) self.tView.setRootIndex(self.root) self.tView.doubleClicked.connect(self.clickAction) self.subdirs = 0 self.current_dir = QDir.homePath() def clickAction(self, index): if index.data() == '..': if self.subdirs > 0: self.current_dir = self.current_dir.rsplit('/', 1)[0] self.tView.setRootIndex( self.dirModel.setRootPath(self.current_dir)) self.subdirs -= 1 # print(QDir(index.parent()).absoluteFilePath()) # self.dirModel.setRootPath(QDir(index.parent()).absolutePath()) elif self.dirModel.fileInfo(index).isDir(): self.subdirs += 1 self.current_dir = self.current_dir + '/' + str(index.data()) self.tView.setRootIndex(index) elif self.dirModel.fileInfo(index).isFile(): extension = index.data().rsplit('.', 1)[1] if extension == 'nc' or extension == 'nc4': subprocess.call('ncview ' + self.current_dir + '/' + index.data(), shell=True) elif extension == 'ncl': self.editor.AddTab(self.current_dir + '/' + index.data())
class AssetBrowser(QMainWindow, Ui_MainWindow): asset_clicked = pyqtSignal(str, str, name='assetClicked') def __init__(self): super(AssetBrowser, self).__init__() self.setupUi(self) self.dir_model = QFileSystemModel() self.dir_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.dir_model.setReadOnly(False) self.dir_view.setModel(self.dir_model) self.dir_view.hideColumn(1) self.dir_view.hideColumn(2) self.dir_view.hideColumn(3) self.file_model = QFileSystemModel() self.file_model.setFilter(QDir.NoDotAndDotDot | QDir.Files) self.file_model.setReadOnly(False) self.file_view.setModel(self.file_model) def open_project(self, project_dir): path = os.path.join(project_dir) self.dir_model.setRootPath(path) self.file_model.setRootPath(path) self.dir_view.setRootIndex(self.dir_model.index(path)) self.file_view.setRootIndex(self.file_model.index(path)) def dir_clicked(self, idx): path = self.dir_model.fileInfo(idx).absoluteFilePath() self.file_view.setRootIndex(self.file_model.setRootPath(path)) def file_doubleclicked(self, idx): fileinfo = self.file_model.fileInfo(idx) path = fileinfo.absoluteFilePath() ext = fileinfo.suffix() self.asset_clicked.emit(path, ext)
class DirectoryTree(QWidget): def __init__(self): super().__init__() self.title = 'PyQt5 file system view' self.left = 10 self.top = 10 self.width = 640 self.height = 480 self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.model = QFileSystemModel() self.model.setRootPath(QDir.rootPath()) self.model.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot) self.tree = QTreeView() self.tree.setModel(self.model) self.tree.hideColumn(1) self.tree.hideColumn(2) self.tree.hideColumn(3) self.tree.setAnimated(False) self.tree.setIndentation(20) self.tree.setSortingEnabled(True) self.tree.setWindowTitle("Dir View") self.tree.resize(640, 480) self.fileModel = QFileSystemModel() self.fileModel.setRootPath(QDir.rootPath()) self.list = QTableView() self.list.setModel(self.fileModel) self.list.setShowGrid(False) self.list.verticalHeader().setVisible(False) self.list.setSelectionBehavior(QTableView().SelectRows) self.tree.clicked.connect(self.onClicked) windowLayout = QHBoxLayout() windowLayout.addWidget(self.tree) windowLayout.addWidget(self.list) self.setLayout(windowLayout) self.show() def onClicked(self, index): path = self.model.fileInfo(index).absoluteFilePath() self.list.setRootIndex(self.fileModel.setRootPath(path))
class MainWindow(QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) path = QDir.currentPath() self.browser_model = QFileSystemModel() self.browser_model.setRootPath(path) self.browser_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.ui.browser.setModel(self.browser_model) self.details_model = QFileSystemModel() self.details_model.setRootPath(path) self.details_model.setFilter(QDir.NoDotAndDotDot | QDir.AllEntries) self.ui.details.setModel(self.details_model) column_count = self.browser_model.columnCount() for i in range(1, column_count): self.ui.browser.hideColumn(i) self.setupUi() def setupUi(self): self.ui.browser.clicked.connect(self.browser_clicked) def browser_clicked(self, index): file_info = self.browser_model.fileInfo(index) path = file_info.absoluteFilePath() self.ui.details.setRootIndex(self.details_model.setRootPath(path))
class FileManager(QWidget, _HalWidgetBase): def __init__(self, parent=None): super(FileManager, self).__init__(parent) self.title = 'PyQt5 file system view - pythonspot.com' self.left = 10 self.top = 10 self.width = 640 self.height = 480 self.default_path = (os.path.join(os.path.expanduser('~'), 'labvcnc/nc_files/examples')) self.user_path = (os.path.join('/media')) self.currentPath = None self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.model = QFileSystemModel() self.model.setRootPath(QDir.currentPath()) self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files) self.model.setNameFilterDisables(False) self.model.setNameFilters(["*.ngc", '*.py']) self.list = QListView() self.list.setModel(self.model) self.updateDirectoryView(self.default_path) self.list.setWindowTitle("Dir View") self.list.resize(640, 480) self.list.clicked[QModelIndex].connect(self.clicked) self.list.activated.connect(self.load) self.list.setAlternatingRowColors(True) self.cb = QComboBox() self.cb.currentTextChanged.connect(self.filterChanged) self.cb.addItems(sorted({'*.ngc', '*.py', '*'})) #self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button = QPushButton() self.button.setText('Media') self.button.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button.setToolTip('Jump to Media directory') self.button.clicked.connect(self.onMediaClicked) self.button2 = QPushButton() self.button2.setText('User') self.button2.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button2.setToolTip('Jump to labvcnc directory') self.button2.clicked.connect(self.onUserClicked) hbox = QHBoxLayout() hbox.addWidget(self.button) hbox.addWidget(self.button2) hbox.addWidget(self.cb) windowLayout = QVBoxLayout() windowLayout.addWidget(self.list) windowLayout.addLayout(hbox) self.setLayout(windowLayout) self.show() def updateDirectoryView(self, path): self.list.setRootIndex(self.model.setRootPath(path)) def filterChanged(self, text): self.model.setNameFilters([text]) def clicked(self, index): # the signal passes the index of the clicked item dir_path = self.model.filePath(index) if self.model.fileInfo(index).isFile(): self.currentPath = dir_path return root_index = self.model.setRootPath(dir_path) self.list.setRootIndex(root_index) def onMediaClicked(self): self.updateDirectoryView(self.user_path) def onUserClicked(self): self.updateDirectoryView(self.default_path) def select_row(self, style): style = style.lower() selectionModel = self.list.selectionModel() row = selectionModel.currentIndex().row() self.rows = self.model.rowCount(self.list.rootIndex()) if style == 'last': row = self.rows elif style == 'up': if row > 0: row -= 1 else: row = 0 elif style == 'down': if row < self.rows: row += 1 else: row = self.rows else: return top = self.model.index(row, 0, self.list.rootIndex()) selectionModel.setCurrentIndex( top, QItemSelectionModel.Select | QItemSelectionModel.Rows) selection = QItemSelection(top, top) selectionModel.clearSelection() selectionModel.select(selection, QItemSelectionModel.Select) def _hal_init(self): if self.PREFS_: last_path = self.PREFS_.getpref('last_file_path', self.default_path, str, 'BOOK_KEEPING') self.updateDirectoryView(last_path) LOG.debug("lAST FILE PATH: {}".format(last_path)) else: LOG.debug("lAST FILE PATH: {}".format(self.default_path)) self.updateDirectoryView(self.default_path) # get current selection and update the path # then if the path is good load it into labvcnc # record it in the preference file if available def load(self): row = self.list.selectionModel().currentIndex() self.clicked(row) fname = self.currentPath if fname is None: return if fname: if self.PREFS_: self.PREFS_.putpref('last_file_path', fname, str, 'BOOK_KEEPING') ACTION.OPEN_PROGRAM(fname) STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME') def up(self): self.select_row('up') def down(self): self.select_row('down')
class FileManager(QWidget, _HalWidgetBase): def __init__(self, parent=None): super(FileManager, self).__init__(parent) self.title = 'Qtvcp File System View' self.left = 10 self.top = 10 self.width = 640 self.height = 480 self._last = 0 if INFO.PROGRAM_PREFIX is not None: self.user_path = os.path.expanduser(INFO.PROGRAM_PREFIX) else: self.user_path = (os.path.join(os.path.expanduser('~'), 'linuxcnc/nc_files')) user = os.path.split(os.path.expanduser('~'))[-1] self.media_path = (os.path.join('/media', user)) temp = [('User', self.user_path), ('Media', self.media_path)] self._jumpList = OrderedDict(temp) self.currentPath = None self.currentFolder = None self.PREFS_ = None self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) pasteBox = QHBoxLayout() self.textLine = QLineEdit() self.textLine.setToolTip('Current Director/selected File') self.pasteButton = QToolButton() self.pasteButton.setEnabled(False) self.pasteButton.setText('Paste') self.pasteButton.setToolTip( 'Copy file from copy path to current directory/file') self.pasteButton.clicked.connect(self.paste) self.pasteButton.hide() pasteBox.addWidget(self.textLine) pasteBox.addWidget(self.pasteButton) self.copyBox = QFrame() hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) self.copyLine = QLineEdit() self.copyLine.setToolTip('File path to copy from, when pasting') self.copyButton = QToolButton() self.copyButton.setText('Copy') self.copyButton.setToolTip('Record current file as copy path') self.copyButton.clicked.connect(self.recordCopyPath) hbox.addWidget(self.copyButton) hbox.addWidget(self.copyLine) self.copyBox.setLayout(hbox) self.copyBox.hide() self.model = QFileSystemModel() self.model.setRootPath(QDir.currentPath()) self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files) self.model.setNameFilterDisables(False) self.model.rootPathChanged.connect(self.folderChanged) self.list = QListView() self.list.setModel(self.model) self.list.resize(640, 480) self.list.clicked[QModelIndex].connect(self.listClicked) self.list.activated.connect(self._getPathActivated) self.list.setAlternatingRowColors(True) self.list.hide() self.table = QTableView() self.table.setModel(self.model) self.table.resize(640, 480) self.table.clicked[QModelIndex].connect(self.listClicked) self.table.activated.connect(self._getPathActivated) self.table.setAlternatingRowColors(True) header = self.table.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.Stretch) header.setSectionResizeMode(1, QHeaderView.ResizeToContents) header.setSectionResizeMode(3, QHeaderView.ResizeToContents) header.swapSections(1, 3) header.setSortIndicator(1, Qt.AscendingOrder) self.table.setSortingEnabled(True) self.table.setColumnHidden(2, True) # type self.table.verticalHeader().setVisible(False) # row count header self.cb = QComboBox() self.cb.currentIndexChanged.connect(self.filterChanged) self.fillCombobox(INFO.PROGRAM_FILTERS_EXTENSIONS) self.cb.setMinimumHeight(30) self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button2 = QToolButton() self.button2.setText('User') self.button2.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button2.setMinimumSize(60, 30) self.button2.setToolTip( 'Jump to User directory.\nLong press for Options.') self.button2.clicked.connect(self.onJumpClicked) self.button3 = QToolButton() self.button3.setText('Add Jump') self.button3.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button3.setMinimumSize(60, 30) self.button3.setToolTip('Add current directory to jump button list') self.button3.clicked.connect(self.onActionClicked) self.settingMenu = QMenu(self) self.button2.setMenu(self.settingMenu) hbox = QHBoxLayout() hbox.addWidget(self.button2) hbox.addWidget(self.button3) hbox.insertStretch(2, stretch=0) hbox.addWidget(self.cb) windowLayout = QVBoxLayout() windowLayout.addLayout(pasteBox) windowLayout.addWidget(self.copyBox) windowLayout.addWidget(self.list) windowLayout.addWidget(self.table) windowLayout.addLayout(hbox) self.setLayout(windowLayout) self.show() def _hal_init(self): if self.PREFS_: last_path = self.PREFS_.getpref('last_loaded_directory', self.user_path, str, 'BOOK_KEEPING') LOG.debug("lAST FILE PATH: {}".format(last_path)) if not last_path == '': self.updateDirectoryView(last_path) else: self.updateDirectoryView(self.user_path) # get all the saved jumplist paths temp = self.PREFS_.getall('FILEMANAGER_JUMPLIST') self._jumpList.update(temp) else: LOG.debug("lAST FILE PATH: {}".format(self.user_path)) self.updateDirectoryView(self.user_path) # install jump paths into toolbutton menu for i in self._jumpList: self.addAction(i) # set recorded columns sort settings self.SETTINGS_.beginGroup("FileManager-{}".format(self.objectName())) sect = self.SETTINGS_.value('sortIndicatorSection', type=int) order = self.SETTINGS_.value('sortIndicatorOrder', type=int) self.SETTINGS_.endGroup() if not None in (sect, order): self.table.horizontalHeader().setSortIndicator(sect, order) # when qtvcp closes this gets called # record jump list paths def _hal_cleanup(self): if self.PREFS_: for i, key in enumerate(self._jumpList): if i in (0, 1): continue self.PREFS_.putpref(key, self._jumpList.get(key), str, 'FILEMANAGER_JUMPLIST') # record sorted columns h = self.table.horizontalHeader() self.SETTINGS_.beginGroup("FileManager-{}".format(self.objectName())) self.SETTINGS_.setValue('sortIndicatorSection', h.sortIndicatorSection()) self.SETTINGS_.setValue('sortIndicatorOrder', h.sortIndicatorOrder()) self.SETTINGS_.endGroup() ######################### # callbacks ######################### # add shown text and hidden filter data from the INI def fillCombobox(self, data): for i in data: self.cb.addItem(i[0], i[1]) def folderChanged(self, data): data = os.path.normpath(data) self.currentFolder = data self.textLine.setText(data) def updateDirectoryView(self, path, quiet=False): if os.path.exists(path): self.list.setRootIndex(self.model.setRootPath(path)) self.table.setRootIndex(self.model.setRootPath(path)) else: LOG.debug( "Set directory view error - no such path {}".format(path)) if not quiet: STATUS.emit( 'error', LOW_ERROR, "File Manager error - No such path: {}".format(path)) # retrieve selected filter (it's held as QT.userData) def filterChanged(self, index): userdata = self.cb.itemData(index) self.model.setNameFilters(userdata) def listClicked(self, index): # the signal passes the index of the clicked item dir_path = os.path.normpath(self.model.filePath(index)) if self.model.fileInfo(index).isFile(): self.currentPath = dir_path self.textLine.setText(self.currentPath) return root_index = self.model.setRootPath(dir_path) self.list.setRootIndex(root_index) self.table.setRootIndex(root_index) def onUserClicked(self): self.showUserDir() def onMediaClicked(self): self.showMediaDir() # jump directly to a saved path shown on the button def onJumpClicked(self): data = self.button2.text() if data.upper() == 'MEDIA': self.showMediaDir() elif data.upper() == 'USER': self.showUserDir() else: temp = self._jumpList.get(data) if temp is not None: self.updateDirectoryView(temp) else: STATUS.emit('error', linuxcnc.OPERATOR_ERROR, 'file jumopath: {} not valid'.format(data)) log.debug('file jumopath: {} not valid'.format(data)) # jump directly to a saved path from the menu def jumpTriggered(self, data): if data.upper() == 'MEDIA': self.button2.setText('{}'.format(data)) self.button2.setToolTip( 'Jump to Media directory.\nLong press for Options.') self.showMediaDir() elif data.upper() == 'USER': self.button2.setText('{}'.format(data)) self.button2.setToolTip( 'Jump to User directory.\nLong press for Options.') self.showUserDir() else: self.button2.setText('{}'.format(data)) self.button2.setToolTip('Jump to directory:\n{}'.format( self._jumpList.get(data))) self.updateDirectoryView(self._jumpList.get(data)) # add a jump list path def onActionClicked(self): i = self.currentFolder try: self._jumpList[i] = i except Exception as e: print(e) button = QAction(QIcon.fromTheme('user-home'), i, self) # weird lambda i=i to work around 'function closure' button.triggered.connect(lambda state, i=i: self.jumpTriggered(i)) self.settingMenu.addAction(button) # get current selection and update the path # then if the path is good load it into linuxcnc # record it in the preference file if available def _getPathActivated(self): if self.list.isVisible(): row = self.list.selectionModel().currentIndex() else: row = self.table.selectionModel().currentIndex() self.listClicked(row) fname = self.currentPath if fname is None: return if fname: self.load(fname) def recordCopyPath(self): data, isFile = self.getCurrentSelected() if isFile: self.copyLine.setText(os.path.normpath(data)) self.pasteButton.setEnabled(True) else: self.copyLine.setText('') self.pasteButton.setEnabled(False) STATUS.emit('error', OPERATOR_ERROR, 'Can only copy a file, not a folder') def paste(self): res = self.copyFile(self.copyLine.text(), self.textLine.text()) if res: self.copyLine.setText('') self.pasteButton.setEnabled(False) ######################## # helper functions ######################## def addAction(self, i): axisButton = QAction(QIcon.fromTheme('user-home'), i, self) # weird lambda i=i to work around 'function closure' axisButton.triggered.connect(lambda state, i=i: self.jumpTriggered(i)) self.settingMenu.addAction(axisButton) def showList(self, state=True): if state: self.table.hide() self.list.show() else: self.table.show() self.list.hide() def showTable(self, state=True): self.showList(not state) def showCopyControls(self, state): if state: self.copyBox.show() self.pasteButton.show() else: self.copyBox.hide() self.pasteButton.hide() def showMediaDir(self, quiet=False): self.updateDirectoryView(self.media_path, quiet) def showUserDir(self, quiet=False): self.updateDirectoryView(self.user_path, quiet) def copyFile(self, s, d): try: shutil.copy(s, d) return True except Exception as e: LOG.error("Copy file error: {}".format(e)) STATUS.emit('error', OPERATOR_ERROR, "Copy file error: {}".format(e)) return False @pyqtSlot(float) @pyqtSlot(int) def scroll(self, data): if data > self._last: self.up() elif data < self._last: self.down() self._last = data # moves the selection up # used with MPG scrolling def up(self): self.select_row('up') # moves the selection down # used with MPG scrolling def down(self): self.select_row('down') def select_row(self, style='down'): style = style.lower() if self.list.isVisible(): i = self.list.rootIndex() selectionModel = self.list.selectionModel() else: i = self.table.rootIndex() selectionModel = self.table.selectionModel() row = selectionModel.currentIndex().row() self.rows = self.model.rowCount(i) if style == 'last': row = self.rows elif style == 'up': if row > 0: row -= 1 else: row = 0 elif style == 'down': if row < self.rows - 1: row += 1 else: row = self.rows - 1 else: return top = self.model.index(row, 0, i) selectionModel.setCurrentIndex( top, QItemSelectionModel.Select | QItemSelectionModel.Rows) selection = QItemSelection(top, top) selectionModel.clearSelection() selectionModel.select(selection, QItemSelectionModel.Select) # returns the current highlighted (selected) path as well as # whether it's a file or not. def getCurrentSelected(self): if self.list.isVisible(): selectionModel = self.list.selectionModel() else: selectionModel = self.table.selectionModel() index = selectionModel.currentIndex() dir_path = os.path.normpath(self.model.filePath(index)) if self.model.fileInfo(index).isFile(): return (dir_path, True) else: return (dir_path, False) # This can be class patched to do something else def load(self, fname=None): try: if fname is None: self._getPathActivated() return self.recordBookKeeping() ACTION.OPEN_PROGRAM(fname) STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME') except Exception as e: LOG.error("Load file error: {}".format(e)) STATUS.emit('error', NML_ERROR, "Load file error: {}".format(e)) # This can be class patched to do something else def recordBookKeeping(self): fname = self.currentPath if fname is None: return if self.PREFS_: self.PREFS_.putpref('last_loaded_directory', self.model.rootPath(), str, 'BOOK_KEEPING') self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING')
class MyWindow(QMainWindow, Form): def __init__(self): Form.__init__(self) QMainWindow.__init__(self) self.setupUi(self) self.setWindowTitle("Automated Homework Correction") # Initializations for the student table on the left self.st_table = MyTable(self) self.st_tab_ind = None # stores the table col. index/text self.persian_font = QFont() # Holds the persian font for the table self.setup_st_table() QVBoxLayout(self.table_frame).addWidget(self.st_table) # Initializations for the Terminal in Terminal tab self.setup_terminal() # Initializations for the part below terminal self.open_code_push_button.clicked.connect(self.open_code) self.open_report_push_button.clicked.connect(self.open_report) self.compile_push_button.clicked.connect(self.compile_hw) self.run_push_button.clicked.connect(self.run_hw) self.prog_type_combo.activated.connect(self.prog_type_changed) self.sel_prog_type = self.prog_type_combo.currentText() # Initializations for the Folder Tree in Folder Tab self.folder_model = QFileSystemModel() self.setup_folder_tree_view() # Miscellaneous initializations self.command = "" # holds the text in console textbox self.hw_path = "" # holds the dropped hw folder path self.sel_hw_path = "" # path of selected hw in the student table self.sel_cn = "" # Selected course name in the cell self.sel_hw_num = 0 # hw num of selected cell self.sel_st_num = 0 # student number of selected cell self.hw_folders = [] # proper and valid homework folders self.prev_row = -1 # holds the previous selected row of table self.sep = "----------------------------------------------------" self.hw_re = re.compile(r"\A(\w{2})[-_](HW(\d+)[-_](\d{7}))\Z", re.IGNORECASE) self.sel_folder_index = None # index of the folder model for treeView self.zip_thread = None # will hold the ZipHandle Thread # Compiler initializations self.c_comp = CCompiler(None) # will hold the C Compiler handle self.c_comp.log_trigger.connect(self.compile_box_update) self.mat_compiler = MATCompiler(None) self.mat_compiler.log_trigger.connect(self.compile_box_update) # OS Specific Initializations self._processes = [] # holds all active processes for Popen self._plat = platform.system() # Linux or Windows self.system_arch = platform.machine() # x86_64 or i386 if "Windows" in self._plat: self.is_linux = False # Used later to know if on linux self.is_windows = True # Windows code editor self.editor = "\"C:\\Program Files\\Sublime Text 3\\subl.exe\" --wait" self.terminal_cmd = r"C:\Windows\System32\cmd.exe /k" self.pdf_viewer = "\"C:\Program Files (x86)\Adobe\Acrobat DC\Acrobat\Acrobat.exe\"" elif "Linux" in self._plat: self.is_linux = True self.is_windows = False self.editor = "/usr/bin/subl --wait" self.pdf_viewer = "/usr/bin/evince" self.terminal_cmd = None else: print("Not a standard OS: use Windows or Linux.") def setup_st_table(self): """ This function is for setting up the table on the left of the dialogue. All initializations are made here.""" self.st_table.dropped_trigger = self.process_hw # file/folder dropped self.st_table.cellClicked.connect(self.hw_clicked) # a cell is clicked self.st_table.setSelectionMode(PyQt5.QtWidgets.QAbstractItemView. SingleSelection) self.st_table.setSelectionBehavior(PyQt5.QtWidgets.QAbstractItemView. SelectRows) # start out with 5 columns self.st_tab_ind = {"CN": 0, "HW_Num": 1, "St_Num": 2, "St_Name": 3, "Folders": 4, "Report": 5} self.st_table.setColumnCount(len(self.st_tab_ind)) # Now put text for the columns and set width if required self.st_table.setHorizontalHeaderItem(self.st_tab_ind["CN"], QTableWidgetItem("CN")) self.st_table.setColumnWidth(self.st_tab_ind["CN"], 30) self.st_table.setHorizontalHeaderItem(self.st_tab_ind["HW_Num"], QTableWidgetItem("HW")) self.st_table.setColumnWidth(self.st_tab_ind["HW_Num"], 31) self.st_table.setHorizontalHeaderItem(self.st_tab_ind["St_Num"], QTableWidgetItem("St. Num")) self.st_table.setColumnWidth(self.st_tab_ind["St_Num"], 70) self.st_table.setHorizontalHeaderItem(self.st_tab_ind["St_Name"], QTableWidgetItem("St. Name")) self.st_table.setColumnWidth(self.st_tab_ind["St_Name"], 105) self.st_table.setHorizontalHeaderItem(self.st_tab_ind["Folders"], QTableWidgetItem("Folders")) self.st_table.setColumnWidth(self.st_tab_ind["Folders"], 100) self.st_table.setHorizontalHeaderItem(self.st_tab_ind["Report"], QTableWidgetItem("Report")) self.st_table.setColumnWidth(self.st_tab_ind["Report"], 100) self.persian_font.setFamily("XW Zar") # Persian font setup for the table self.persian_font.setPointSize(11) def setup_terminal(self): self.compile_box.setTextColor(QColor(237, 238, 240)) self.compile_box.setText("Drag your folder to the table ...") def setup_folder_tree_view(self): self.folder_tree_view.setModel(self.folder_model) self.folder_tree_view.doubleClicked.connect(self.open_file_folder) self.folder_tree_view.expanded.connect(self.expanded) self.folder_tree_view.setColumnWidth(0, 350) self.folder_tree_view.setColumnWidth(1, 50) self.folder_tree_view.setColumnWidth(2, 50) self.folder_tree_view.hideColumn(3) def enable_config(self, yes): """ This functions enables the config part if yes is true """ items = [self.open_code_push_button, self.run_push_button, self.open_report_push_button, self.compile_push_button, self.prog_type_combo] if yes: method = methodcaller('setEnabled', True) else: method = methodcaller('setEnabled', False) list(map(method, items)) # Runs setEnabled on all of the items @pyqtSlot(str) def process_hw(self, path): # path is DROPPED into the table self.hw_path = path.strip() # removes \n etc # a little clean up is necessary for the path self.hw_path = os.path.normpath(self.hw_path).lstrip("file:") if self.is_linux: self.hw_path = os.path.join('/', self.hw_path) # put a / at start elif self.is_windows: # / should be \ self.hw_path = self.hw_path.replace('/', os.sep).lstrip(os.sep) # Update the folder tree table self.folder_model.setRootPath(self.hw_path) self.folder_tree_view.setRootIndex(self.folder_model.index(self.hw_path)) self.hw_folders.clear() # clear previous homework folders(if any) self.st_table.clearContents() # table contents(if any) not col. headers self.command = "" # reset the console output if os.path.isfile(path): # TODO: single file HW print("Single File is not yet implemented") self.compile_box_update(self.hw_path) # put folder path in terminal # Retrieve the zip files only and sort them files = os.listdir(self.hw_path) files = [f for f in files if f.lower().endswith(".zip")] files.sort() # Setting up the zip thread self.zip_thread = ZipHandle(self.hw_path, files, self.hw_re) self.zip_thread.log_trigger.connect(self.compile_box_update) self.zip_thread.hw_add_trigger.connect(self.table_hw_add) self.zip_thread.start() @pyqtSlot(int, int) def hw_clicked(self, row, _): """ A Cell is clicked, row, col is also passed in here """ if row == self.prev_row: # if double selecting a row, deselect self.st_table.clearSelection() self.prev_row = -1 self.enable_config(False) return else: self.prev_row = row # We use this event handler since it does similar thing self.closeEvent(None) # Retrieve other information of the hw from different columns self.sel_cn = self.st_table.item(row, self.st_tab_ind["CN"]).text() self.sel_hw_num = self.st_table.item(row, self.st_tab_ind["HW_Num"]).text() self.sel_st_num = self.st_table.item(row, self.st_tab_ind["St_Num"]).text() # This part updates the folder tree self.sel_hw_path = os.path.join(self.hw_path, "{}-HW{}-{}".format( self.sel_cn, self.sel_hw_num, self.sel_st_num)) folder_index = self.folder_model.index(self.sel_hw_path) self.folder_tree_view.collapseAll() self.folder_tree_view.expand(folder_index) # triggers expanded # Enabling the buttons below terminal self.enable_config(True) @pyqtSlot() def open_code(self): """ This event handler is run whenever user clicks open code button""" # TODO: Add support for the editor if in other directories p = Popen(shlex.split(self.editor + ' "' + self.sel_hw_path + '"'), shell=False, start_new_session=True) # open code editor self._processes.append(p) @pyqtSlot() def open_report(self): row = self.st_table.currentRow() sel_rep_name = self.st_table.item(row, self.st_tab_ind["Report"]).text() if sel_rep_name == "N/A": self.compile_box_update("Can not find report file.") return sel_report_path = os.path.join(self.sel_hw_path, sel_rep_name) pdf_cmd = shlex.split(self.pdf_viewer) pdf_cmd.extend([sel_report_path]) p = Popen(pdf_cmd, shell=False, start_new_session=True) # open pdf self._processes.append(p) @pyqtSlot(int) def prog_type_changed(self, index): self.sel_prog_type = self.prog_type_combo.currentText() if self.sel_prog_type != "C++": # No compilation step except C++ self.compile_push_button.setVisible(False) else: self.compile_push_button.setVisible(True) @pyqtSlot() def compile_hw(self): # Compile push button is clicked """ In this function the selected hw path is compiled. """ if self.sel_prog_type == "C++": self.c_comp.change_root(self.sel_hw_path) self.compile_box_update("{}: C++".format(os.path.basename( self.sel_hw_path))) self.compile_box_update("Generating Makefile if needed ...") self.c_comp.generate_makefiles() self.compile_box_update("\nCompiling the Questions, Wait ...") self.c_comp.compile() # compiles all the folders with proper C++ elif self.sel_prog_type == "Matlab": pass elif self.sel_prog_type == "Python": pass @pyqtSlot() def run_hw(self): """ This function is run when user clicks on Run button """ if self.sel_prog_type == "C++": comp = self.c_comp elif self.sel_prog_type == "Python": # comp = self.py_comp pass elif self.sel_prog_type == "Matlab": comp = self.mat_compiler comp.change_root(self.sel_hw_path) script_files = self.mat_compiler.search_scripts() if len(script_files) == 0: self.compile_box_update("Did not find any script to run.") return self.compile_box_update("{}: Execute".format(self.sel_prog_type)) comp.exec() # execute proper compiler self.compile_box_update("{0}\n{0}".format(self.sep)) @pyqtSlot(QModelIndex) def expanded(self, index): # Tree view is expanded at one of the indexes # Disable this line, since it decreases the width, 1 level is only open # self.folder_tree_view.resizeColumnToContents(0) if index != None: self.folder_tree_view.setCurrentIndex(index) self.folder_tree_view.scrollTo(index) @pyqtSlot(QModelIndex) def open_file_folder(self, index): # double clicked on something """ This function can open certian filetypes. A handler needs to open the file. For the moment only pdf files are opened.""" path = self.folder_model.fileInfo(index).absoluteFilePath() if os.path.isdir(path): # No need to do anything return if self.is_linux: if path.lower().endswith(".pdf"): p = Popen(shlex.split(self.pdf_viewer + "\"" + path + "\""), shell=False, start_new_session=True) self._processes.append(p) def table_hw_add(self, hw_folder): self.hw_folders.append(hw_folder) hw_ls = os.listdir(os.path.join(self.hw_path, hw_folder)) hw_dirs = [item for item in hw_ls if os.path.isdir(os.path.join(self.hw_path, hw_folder, item))] hw_files = [item for item in hw_ls if os.path.isfile(os.path.join(self.hw_path, hw_folder, item))] course_name, file_name, hw_num, st_num = self.hw_re.match( hw_folder).groups() cur_row = len(self.hw_folders) - 1 self.st_table.insertRow(cur_row) self.st_table.setItem(cur_row, self.st_tab_ind["CN"], QTableWidgetItem(course_name)) # hw_num self.st_table.item(cur_row, self.st_tab_ind["CN"]).\ setTextAlignment(QtCore.Qt.AlignCenter) self.st_table.setItem(cur_row, self.st_tab_ind["HW_Num"], QTableWidgetItem(hw_num)) # hw_num self.st_table.item(cur_row, self.st_tab_ind["HW_Num"]).\ setTextAlignment(QtCore.Qt.AlignCenter) self.st_table.setItem(cur_row, self.st_tab_ind["St_Num"], QTableWidgetItem(st_num)) # st_num self.st_table.item(cur_row, self.st_tab_ind["St_Num"]). \ setTextAlignment(QtCore.Qt.AlignCenter) st_name_item = QTableWidgetItem("وارد نشده است") st_name_item.setFont(self.persian_font) self.st_table.setItem(cur_row, self.st_tab_ind["St_Name"], st_name_item) self.st_table.item(cur_row, self.st_tab_ind["St_Name"]). \ setTextAlignment(QtCore.Qt.AlignHCenter) # ignore chars from the homework folder names in the table, # e.g.: Q1, Q2 -> 1, 2 if len(hw_dirs) > 0: hw_dirs_str = ' '.join(hw_dirs) hw_dirs_str = [c for c in hw_dirs_str if not c.isalpha()] hw_dirs_str.sort() hw_dirs_str = ' '.join(hw_dirs_str) # convert back to str else: hw_dirs_str = "N/A" self.st_table.setItem(cur_row, self.st_tab_ind["Folders"], QTableWidgetItem(hw_dirs_str)) # hw folders # Finding the report file name and store in report_file variable if len(hw_files) > 0: # filter out non pdf files hw_files = [f for f in hw_files if f.lower().endswith(".pdf")] if len(hw_files) > 1: self.compile_box_update("{}: multiple PDFs".format(hw_folder)) if len(hw_files) > 0: # can be greater than 1, only output one report_file = hw_files[0] else: report_file = "N/A" else: # No report file available report_file = "N/A" self.st_table.setItem(cur_row, self.st_tab_ind["Report"], QTableWidgetItem(report_file)) #QApplication.instance().processEvents() def compile_box_update(self, text): if text == "": # Ignore input return self.command += text + "\n" self.compile_box.setText(self.command) self.compile_box.moveCursor(PyQt5.QtGui.QTextCursor.End) QApplication.instance().processEvents() # This is called wihen the dialog is closed by pressing x def closeEvent(self, event): self.c_comp.kill_windows() self.mat_compiler.kill_windows() if self.is_linux: for p in self._processes: os.killpg(os.getpgid(p.pid), signal.SIGTERM) self._processes.clear() elif self.is_windows: # TODO: Add support for windows pass
class App(QMainWindow, QWidget): # 창의 대부분의 기능 def __init__(self): # 창 기본 세팅 설정 super().__init__() # Window options! self.title = 'HexQT' self.left = 0 self.top = 0 self.width = 1280 self.height = 840 self.rowSpacing = 4 # How many bytes before a double space. self.rowLength = 16 # 헥사 창에 얼마나 많은 byte 가 들어갈 것인지 self.byteWidth = 4 # How many bits to include in a byte. self.mode = Mode.READ self.initUI() def openFile(self): fileSelect = FileSelector() fileName = fileSelect.fileName self.readFile(fileName) # readFile ... Reads file data from a file in the form of bytes and generates the text for the hex-editor. def readFile(self, fileName): fileData = '' if fileName: with open(fileName, 'rb') as fileObj: fileData = fileObj.read() self.generateView(fileData) # saveFile ... Method for saving the edited hex file. def saveFile(self): print('Saved!') # generateView ... Generates text view for hexdump likedness. def generateView(self, text): space = ' ' bigSpace = ' ' * 4 rowSpacing = self.rowSpacing rowLength = self.rowLength offset = 0 offsetText = '' mainText = '' asciiText = '' for chars in range(1, len(text) + 1): byte = text[chars - 1] char = chr(text[chars - 1]) # Asciitext 는 오른쪽 출력부 if char is ' ': asciiText += '.' elif char is '\n': asciiText += '!' else: asciiText += char # main text 가 중앙에 있는것 mainText += format(byte, '0' + str(self.byteWidth) + 'x') if chars % rowLength is 0: offsetText += format(offset, '08x') + '\n' mainText += '\n' asciiText += '\n' elif chars % rowSpacing is 0: mainText += space * 2 else: mainText += space offset += len(char) self.offsetTextArea.setText(offsetText) self.mainTextArea.setText(mainText) self.asciiTextArea.setText(asciiText) # openFile ... Opens a file directory and returns the filename. # highlightMain ... Bi-directional highlighting from main. def highlightMain(self): # Create and get cursors for getting and setting selections. highlightCursor = QTextCursor(self.asciiTextArea.document()) # asciitextArea의 처음을 가르치는 커서를 구성 cursor = self.mainTextArea.textCursor() # 커서의 위치의 사본을 따서 복사 함 # Clear any current selections and reset text color. highlightCursor.select(QTextCursor.Document) highlightCursor.setCharFormat(QTextCharFormat()) highlightCursor.clearSelection() # Information about where selections and rows start. selectedText = cursor.selectedText() # The actual text selected. selectionStart = cursor.selectionStart() selectionEnd = cursor.selectionEnd() mainText = self.mainTextArea.toPlainText().replace('\n', 'A') #mainText = self.mainTextArea.toPlainText() totalBytes = 0 for char in mainText[selectionStart:selectionEnd]: if char is not ' ': totalBytes += len(char) asciiStart = 0 for char in mainText[:selectionStart]: if char is not ' ': asciiStart += len(char) totalBytes = round(totalBytes / self.byteWidth) asciiStart = round(asciiStart / self.byteWidth) asciiEnd = asciiStart + totalBytes asciiText = self.asciiTextArea.toPlainText() # Select text and highlight it. highlightCursor.setPosition(asciiStart, QTextCursor.MoveAnchor) highlightCursor.setPosition(asciiEnd, QTextCursor.KeepAnchor) highlight = QTextCharFormat() highlight.setBackground(Qt.darkCyan) highlightCursor.setCharFormat(highlight) highlightCursor.clearSelection() # highlightAscii ... Bi-directional highlighting from ascii. def highlightAscii(self): selectedText = self.asciiTextArea.textCursor().selectedText() # offsetJump ... Creates a dialogue and gets the offset to jump to and then jumps to that offset. def offsetJump(self): # input dialog 를 활용 하여 jump to ofsset 을 만듭니다. jumpText = InputDialogue('Jump to Offset', 'Offset').dialogueReponse jumpOffset = 0xF mainText = self.mainTextArea.toPlainText() mainText = mainText.strip().replace(' ', ' ') textCursor = self.mainTextArea.textCursor() # createMainView ... Creates the primary view and look of the application (3-text areas.) def createMainView(self): qhBox = QHBoxLayout() qhBox2 = QHBoxLayout() qvBox = QVBoxLayout() self.dirModel = QFileSystemModel() self.dirModel.setRootPath('') self.fileModel = QFileSystemModel() self.tree = QTreeView() self.list = QListView() self.tree.setModel(self.dirModel) self.list.setModel(self.fileModel) self.tree.clicked.connect(self.tree_on_clicked) self.list.clicked.connect(self.list_on_clicked) self.mainTextArea = QTextEdit() self.offsetTextArea = QTextEdit() self.asciiTextArea = QTextEdit() # Initialize them all to read only. self.mainTextArea.setReadOnly(True) self.asciiTextArea.setReadOnly(True) self.offsetTextArea.setReadOnly(True) # Create the fonts and styles to be used and then apply them. font = QFont("DejaVu Sans Mono", 11, QFont.Normal, True) self.mainTextArea.setFont(font) self.asciiTextArea.setFont(font) self.offsetTextArea.setFont(font) #self.offsetTextArea.setTextColor(Qt.red) # Syncing scrolls. syncScrolls(self.mainTextArea, self.asciiTextArea, self.offsetTextArea) # Highlight linking. BUG-GY self.mainTextArea.selectionChanged.connect(self.highlightMain) self.asciiTextArea.selectionChanged.connect(self.highlightAscii) qhBox.addWidget(self.offsetTextArea, 1) qhBox.addWidget(self.mainTextArea, 6) qhBox.addWidget(self.asciiTextArea, 2) qhBox2.addWidget(self.tree) qhBox2.addWidget(self.list) qvBox.addLayout(qhBox2) qvBox.addLayout(qhBox) return qvBox def tree_on_clicked(self, index): path = self.dirModel.fileInfo(index).absoluteFilePath() self.list.setRootIndex(self.fileModel.setRootPath(path)) def list_on_clicked(self, index): path = self.fileModel.fileInfo(index).absoluteFilePath() #self.openbyList(self,path) self.readFile(path) # initUI ... Initializes the min look of the application. def initUI(self): # Initialize basic window options. self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) # Center the window. qtRectangle = self.frameGeometry() centerPoint = QDesktopWidget().availableGeometry().center() qtRectangle.moveCenter(centerPoint) self.move(qtRectangle.topLeft()) # Creates a menu bar, (file, edit, options, etc...) mainMenu = self.menuBar() # Menus for window. fileMenu = mainMenu.addMenu('File') editMenu = mainMenu.addMenu('Edit') viewMenu = mainMenu.addMenu('View') helpMenu = mainMenu.addMenu('Help') # FILE MENU --------------------------------------- # Open button. openButton = QAction(QIcon(), 'Open', self) openButton.setShortcut('Ctrl+O') openButton.setStatusTip('Open file') openButton.triggered.connect(self.openFile) # Save button. saveButton = QAction(QIcon(), 'Save', self) saveButton.setShortcut('Ctrl+S') saveButton.setStatusTip('Open file') saveButton.triggered.connect(self.saveFile) # Optional exit stuff. exitButton = QAction(QIcon(), 'Exit', self) exitButton.setShortcut('Ctrl+Q') exitButton.setStatusTip('Exit application') exitButton.triggered.connect(self.close) fileMenu.addAction(openButton) fileMenu.addAction(saveButton) fileMenu.addAction(exitButton) # EDIT MENU --------------------------------------- # Jump to Offset offsetButton = QAction(QIcon(), 'Jump to Offset', self) offsetButton.setShortcut('Ctrl+J') offsetButton.setStatusTip('Jump to Offset') offsetButton.triggered.connect(self.offsetJump) editMenu.addAction(offsetButton) # Creating a widget for the central widget thingy. centralWidget = QWidget() centralWidget.setLayout(self.createMainView()) self.setCentralWidget(centralWidget) # Show our masterpiece. self.show()
class FileBrowser(QTreeView): def __init__(self, parent=None, textPad=None, notebook=None, codeView=None): super().__init__() self.path = self.checkPath(os.getcwd()) self.filename = None self.text = None self.initItems() self.textPad = textPad self.notebook = notebook self.codeView = codeView self.mainWindow = parent self.index = None self.copySourceFilePath = None # copy / paste items self.copySourceFileName = None self.isCopyFileFolder = None self.setStyleSheet(""" border: 5 px; background-color: black; color: white; alternate-background-color: #FFFFFF; selection-background-color: #3b5784; """) # Contextmenu self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.openMenu) self.popMenu = QMenu() self.popMenu.setStyleSheet(""" color: #FFFFFF; background-color: #2c2c2c; selection-background-color: #3b5784; alternate-background-color: #FFFFFF; """) infoAction = QAction('Info', self) infoAction.triggered.connect(self.onInfo) createFolderAction = QAction('Create New Folder', self) createFolderAction.triggered.connect(self.onCreateNewFolder) copyAction = QAction('Copy Item', self) copyAction.triggered.connect(self.onCopy) pasteAction = QAction('Paste Item', self) pasteAction.triggered.connect(self.onPaste) renameAction = QAction('Rename Item', self) renameAction.triggered.connect(self.onRename) deleteAction = QAction('Delete Item', self) deleteAction.triggered.connect(self.onDelete) terminalAction = QAction('Open Terminal', self) terminalAction.triggered.connect(self.onTerminal) self.popMenu.addAction(infoAction) self.popMenu.addSeparator() self.popMenu.addAction(createFolderAction) self.popMenu.addSeparator() self.popMenu.addAction(copyAction) self.popMenu.addAction(pasteAction) self.popMenu.addAction(renameAction) self.popMenu.addSeparator() self.popMenu.addAction(deleteAction) self.popMenu.addSeparator() self.popMenu.addAction(terminalAction) def openMenu(self, position): # -> open ContextMenu self.popMenu.exec_(self.mapToGlobal(position)) def onInfo(self): if not self.index: return index = self.index indexItem = self.model.index(index.row(), 0, index.parent()) fileName, filePath, fileDir, fileInfo = self.getFileInformation() bundle = fileInfo.isBundle() # bool dir = fileInfo.isDir() # bool file = fileInfo.isFile() # bool executable = fileInfo.isExecutable() # bool readable = fileInfo.isReadable() # bool writable = fileInfo.isWritable() # bool created = fileInfo.created() # QDateTime #modified = fileInfo.lastModified() # QDateTime owner = fileInfo.owner() # QString size = fileInfo.size() # QInt s = format(size, ',d') text = '' text += 'Type:\t' if bundle: text += 'Bundle\n\n' if dir: text += 'Path\n\n' if file: text += 'File\n\n' if readable: text += 'read:\tyes\n' else: text += 'read:\tno\n' if writable: text += 'write:\tyes\n' else: text += 'write:\tno\n' if executable: text += 'exec:\tyes\n\n' else: text += 'exec:\tno\n\n' text += 'size:\t' + str(s) + ' bytes' + '\n' text += 'owner:\t' + owner + '\n' text += 'created:\t' + str(created.date().day()) + '.' + \ str(created.date().month()) + '.' + \ str(created.date().year()) + ' ' + \ created.time().toString() + '\n' q = MessageBox(QMessageBox.Information, fileName, text, QMessageBox.NoButton) q.exec_() def onCreateNewFolder(self): if not self.index: return else: index = self.index fileName, filePath, fileDir, fileInfo = self.getFileInformation() path = os.getcwd() + '/' path = self.checkPath(path) index = self.index fileName, filePath, fileDir, fileInfo = self.getFileInformation() dialog = EnterDialog(self.mainWindow, fileName, \ filePath, fileDir, fileInfo, False, path) dialog.exec_() # return def onCopy(self): if not self.index: return fileName, filePath, fileDir, fileInfo = self.getFileInformation() if fileName == '..': self.clearSelection() self.mainWindow.statusBar.showMessage("can't copy this item !", 3000) self.copySourceFilePath = None self.copySourceFileName = None self.isCopyFileFolder = None return if fileDir: self.copySourceFilePath = filePath self.copySourceFileName = fileName self.isCopyFileFolder = True self.mainWindow.statusBar.showMessage('Path: <' + \ self.copySourceFileName + \ '> marked', 3000) else: self.copySourceFilePath = filePath self.copySourceFileName = fileName self.mainWindow.statusBar.showMessage('File: <' + \ self.copySourceFileName + \ '> marked', 3000) def onPaste(self): if not self.index: return if not self.copySourceFilePath: self.mainWindow.statusBar.showMessage('nothing marked !', 3000) return if not self.copySourceFileName: self.mainWindow.statusBar.showMessage('nothing marked !', 3000) return fileName, filePath, fileDir, fileInfo = self.getFileInformation() rootPath = os.getcwd() rootPath = self.checkPath(rootPath) fileList = os.listdir(self.path) # File list at current path if fileName == '..': # clicked on '..' rootPath = os.getcwd() rootPath = self.checkPath(rootPath) if fileDir and self.isCopyFileFolder: # copy path to another path if fileName == '..': path = os.getcwd() path = self.checkPath(path) else: path = filePath newPath = path + '/' + self.copySourceFileName fileList = os.listdir(path) if self.copySourceFileName in fileList: q = MessageBox( QMessageBox.Warning, "Error", "Another path with the same name already exists.", QMessageBox.NoButton) q.exec_() self.resetMarkedItems(True) return if self.copySourceFilePath in newPath: q = MessageBox(QMessageBox.Critical, 'Error', 'Name of path already exists in new path', QMessageBox.NoButton) q.exec_() self.resetMarkedItems(True) return try: os.mkdir(newPath) self.copytree(self.copySourceFilePath, newPath) self.mainWindow.statusBar.showMessage('Done !', 3000) except Exception as e: q = MessageBox(QMessageBox.Critical, "Error", str(e), QMessageBox.NoButton) q.exec_() self.resetMarkedItems(True) return elif fileDir and not self.isCopyFileFolder: # copy file to path if fileName == '..': path = os.getcwd() path = self.checkPath(path) else: path = filePath fileList = os.listdir(path) # File list at current path if self.copySourceFileName in fileList: result = MessageBox(QMessageBox.Warning, "Warning", "File already exists.\n" + "Continue ?", QMessageBox.Yes | QMessageBox.No) if (result.exec_() == QMessageBox.Yes): try: shutil.copy(self.copySourceFilePath, path) self.mainWindow.statusBar.showMessage('Done !', 3000) except Exception as e: q = MessageBox(QMessageBox.Critical, "Error", str(e), QMessageBox.NoButton) q.exec_() self.resetMarkedItems(True) return else: self.resetMarkedItems() return else: try: shutil.copy(self.copySourceFilePath, path) self.mainWindow.statusBar.showMessage('Done !', 3000) except Exception as e: q = MessageBox(QMessageBox.Critical, "Error", str(e), QMessageBox.NoButton) q.exec_() self.resetMarkedItems(True) return elif not fileDir and self.isCopyFileFolder: # copy path to selected file -> correct this user input ... newPath = rootPath + '/' + self.copySourceFileName if self.copySourceFileName in fileList: q = MessageBox( QMessageBox.Information, "Error", "Another path with the same name already exists.", QMessageBox.NoButton) q.exec_() self.resetMarkedItems(True) return try: os.mkdir(newPath) self.copytree(self.copySourceFilePath, newPath) self.mainWindow.statusBar.showMessage('Done !', 3000) except Exception as e: q = MessageBox(QMessageBox.Critical, "Error", str(e), QMessageBox.NoButton) q.exec_() self.resetMarkedItems(True) return elif not fileDir and not self.isCopyFileFolder: # user copy file to another file -> correct this input fileList = os.listdir(rootPath) # File list in current path if self.copySourceFileName in fileList: result = MessageBox( QMessageBox.Warning, "Warning", "File with this name already exists !" + "Continue ?", QMessageBox.Yes | QMessageBox.No) if (result.exec_() == QMessageBox.Yes): try: shutil.copy(self.copySourceFilePath, rootPath) self.mainWindow.statusBar.showMessage('Done !', 3000) except Exception as e: q = MessageBox(QMessageBox.Critical, "Error", str(e), QMessageBox.NoButton) q.exec_() self.resetMarkedItems(True) return else: self.resetMarkedItems(True) return else: try: shutil.copy(self.copySourceFilePath, rootPath) self.mainWindow.statusBar.showMessage('Done !', 3000) except Exception as e: q = MessageBox(QMessageBox.Critical, "Error", str(e), QMessageBox.Ok) q.exec_() self.resetMarkedItems(True) return self.resetMarkedItems() def resetMarkedItems(self, showMessage=False): # reset marked items self.copySourceFilePath = None self.copySourceFileName = None self.isCopyFileFolder = None if showMessage: self.mainWindow.statusBar.showMessage('Mark removed !', 3000) # copy path with subfolder # thanks to stackoverflow.com ..... ! def copytree(self, src, dst, symlinks=False, ignore=None): if not os.path.exists(dst): os.makedirs(dst) if not os.path.exists(src): os.makedirs(src) for item in os.listdir(src): s = os.path.join(src, item) d = os.path.join(dst, item) if os.path.isdir(s): self.copytree(s, d, symlinks, ignore) else: if not os.path.exists( d) or os.stat(s).st_mtime - os.stat(d).st_mtime > 1: shutil.copy2(s, d) def onRename(self): if not self.index: return fileName, filePath, fileDir, fileInfo = self.getFileInformation() dialog = EnterDialog(self.mainWindow, fileName, filePath, fileDir, fileInfo, True) dialog.exec_() def onDelete(self): if not self.index: return fileName, filePath, fileDir, fileInfo = self.getFileInformation() if fileDir: if fileName == '..': self.mainWindow.statusBar.showMessage( 'can not delete this item !', 3000) return else: result = MessageBox(QMessageBox.Warning, 'Delete directory', '<b>' + filePath + '</b>' + " ?", QMessageBox.Yes | QMessageBox.No) if (result.exec_() == QMessageBox.Yes): try: shutil.rmtree(filePath) self.mainWindow.statusBar.showMessage('Done !', 3000) self.resetMarkedItems() except Exception as e: q = MessageBox(QMessageBox.Critical, "Error", str(e), QMessageBox.NoButton) q.exec_() self.resetMarkedItems(True) else: return else: pathList = filePath.split('/')[:-1] path = '' for elem in pathList: path += elem + '/' file = filePath.split('/')[-1] result = MessageBox(QMessageBox.Warning, 'Delete file', path + "<b>" + file + "</b>" + " ?", QMessageBox.Yes | QMessageBox.No) if (result.exec_() == QMessageBox.Yes): try: os.remove(filePath) self.mainWindow.statusBar.showMessage('Done !', 3000) except Exception as e: q = MessageBox(QMessageBox.Critical, "Error", str(e), QMessageBox.NoButton) q.exec_() self.resetMarkedItems(True) def onTerminal(self): c = Configuration() system = c.getSystem() command = c.getTerminal(system) thread = RunThread(command) thread.start() def initItems(self): font = QFont() font.setPixelSize(16) self.prepareModel(os.getcwd()) self.setToolTip(os.getcwd()) # prepare drag and drop self.setDragEnabled(False) sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.setSizePolicy(sizePolicy) self.setAutoExpandDelay(2) self.setAlternatingRowColors(False) self.setAnimated(False) self.setIndentation(20) self.setSortingEnabled(False) self.setRootIsDecorated(False) self.setPalette(QPalette(Qt.black)) self.verticalScrollBar().setStyleSheet("""border: 20px solid black; background-color: darkgreen; alternate-background-color: #FFFFFF;""") self.horizontalScrollBar().setStyleSheet("""border: 20px solid black; background-color: darkgreen; alternate-background-color: #FFFFFF;""") self.setFont(font) # signals self.doubleClicked.connect(self.onDoubleClicked) self.clicked.connect(self.onClicked) self.pressed.connect(self.onClicked) #self.entered.connect(self.onEntered) self.columnMoved() # that hides the size, file type and last modified colomns self.setHeaderHidden(True) self.hideColumn(1) self.hideColumn(2) self.hideColumn(3) self.resize(400, 400) def prepareModel(self, path): self.model = QFileSystemModel() self.model.setRootPath(path) #model.setFilter(QDir.AllDirs |QDir.NoDotAndDotDot | QDir.AllEntries) self.model.setFilter(QDir.Files | QDir.AllDirs | QDir.NoDot | QDir.Hidden) #self.model.setNameFilters(self.filter) self.model.rootPathChanged.connect(self.onRootPathChanged) self.fsindex = self.model.setRootPath(path) self.setModel(self.model) self.setRootIndex(self.fsindex) def checkPath(self, path): if '\\' in path: path = path.replace('\\', '/') return path def getFileInformation(self): index = self.index indexItem = self.model.index(index.row(), 0, index.parent()) fileName = self.model.fileName(indexItem) filePath = self.model.filePath(indexItem) fileDir = self.model.isDir(indexItem) fileInfo = self.model.fileInfo(indexItem) fileName = self.checkPath(fileName) filePath = self.checkPath(filePath) return (fileName, filePath, fileDir, fileInfo) def onClicked(self, index): self.index = index #.... index des FileSystemModels indexItem = self.model.index(index.row(), 0, index.parent()) fileName, filePath, fileDir, fileInfo = self.getFileInformation() self.setToolTip(filePath) if fileDir: self.path = self.checkPath(os.getcwd()) self.filename = None else: self.filename = filePath self.path = self.checkPath(os.getcwd()) #print('self.filename: ', self.filename) #print('self.path: ', self.path) def refresh(self, dir=None): if not dir: dir = self.checkPath(os.getcwd()) else: dir = dir self.model.setRootPath(dir) if self.rootIsDecorated: self.setRootIsDecorated(False) self.clearSelection() def onDoubleClicked(self, index): self.index = index #.... wie oben ... def onClicked(...): indexItem = self.model.index(index.row(), 0, index.parent()) fileName, filePath, fileDir, fileInfo = self.getFileInformation() if fileDir: filePath = self.checkPath(filePath) try: os.chdir(filePath) except Exception as e: self.mainWindow.statusBar.showMessage(str(e), 3000) self.path = self.checkPath(os.getcwd()) self.model.setRootPath(filePath) if self.rootIsDecorated: self.setRootIsDecorated(False) else: self.filename = filePath try: with open(self.filename, 'r') as f: self.text = f.read() except Exception as e: self.mainWindow.statusBar.showMessage(str(e), 3000) self.filename = None return # debug if self.textPad: if not self.textPad.filename: editor = CodeEditor(self.mainWindow) editor.setText(self.text) editor.filename = filePath self.notebook.newTab(editor) self.textPad = editor x = self.notebook.count() # number of tabs index = x - 1 self.notebook.setCurrentIndex(index) tabName = os.path.basename(editor.filename) self.notebook.setTabText(x, tabName) self.textPad = editor #self.textPad.filename = filePath else: editor = CodeEditor(self.mainWindow) editor.setText(self.text) editor.filename = filePath tabName = os.path.basename(editor.filename) self.notebook.newTab(editor) x = self.notebook.count() # number of tabs index = x - 1 self.notebook.setCurrentIndex(index) self.textPad = editor #self.textPad.filename = filePath if not self.textPad: editor = CodeEditor(self.mainWindow) editor.filename = None self.notebook.newTab(editor) x = self.notebook.count() index = x - 1 self.notebook.setCurrentIndex(index) self.textPad = editor #self.textPad.filename = filePath # make codeView codeViewList = self.codeView.makeDictForCodeView(self.text) self.codeView.updateCodeView(codeViewList) # update textPad Autocomplete autocomplete = Qsci.QsciAPIs(self.textPad.lexer) self.textPad.autocomplete = autocomplete self.textPad.setPythonAutocomplete() self.clearSelection() def onRootPathChanged(self): self.setModel(None) self.setModel(self.model) self.fsindex = self.model.setRootPath(QDir.currentPath()) self.setRootIndex(self.fsindex) sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.setSizePolicy(sizePolicy) self.setAutoExpandDelay(2) self.setAlternatingRowColors(False) self.setAnimated(True) self.setIndentation(20) self.setSortingEnabled(False) self.setRootIsDecorated(False) self.setHeaderHidden(True) self.hideColumn(1) self.hideColumn(2) self.hideColumn(3) self.setToolTip(QDir.currentPath()) self.path = os.getcwd() self.path = self.checkPath(self.path)
class MainUI(QMainWindow): def __init__(self): super().__init__() uic.loadUi('interface.ui', self) self.zss = ZSSMain('zss.db') # Адресная строка self.button_path.clicked.connect(self.change_path) # Дерево файлов self.model_file = QFileSystemModel() self.model_file.setRootPath('') self.tree_file.setModel(self.model_file) self.tree_file.clicked.connect(self.tree_file_click) self.tree_file.doubleClicked.connect(self.tree_file_dclick) self.tree_file.customContextMenuRequested.connect( self.tree_file_rclick) self.tree_file.setContextMenuPolicy(Qt.CustomContextMenu) # Контекстное меню дерева файлов self.cmenu_tree_file = QMenu() self.cmenu_tree_file.addAction(self.rmenu_open) self.cmenu_tree_file.addAction(self.rmenu_delete) self.submenu_tree_file = QMenu() self.submenu_tree_file.setTitle("Добавить в БД") self.submenu_tree_file.addAction(self.new_doc) self.submenu_tree_file.addAction(self.new_img) self.cmenu_tree_file.addMenu(self.submenu_tree_file) # Привязка действий дерева файлов к функциям self.rmenu_open.triggered.connect(self.action_file_open) self.rmenu_delete.triggered.connect(self.action_file_del) self.new_doc.triggered.connect(self.action_new_doc) # Таблица атрибутов self.model_attr = QStandardItemModel() self.table_file.setModel(self.model_attr) def change_path(self): # Переход по ссылке в адресной строке index = self.model_file.index(self.line_path.text()) self.tree_file.setCurrentIndex(index) self.tree_file.setExpanded(index, True) self.tree_file.scrollTo(index) def tree_file_click(self, index): # Выделение объекта в дереве файлов info = self.model_file.fileInfo(index) record_dict = ZSSRecord(info).getDict() print(record_dict) self.model_attr = QStandardItemModel() for item in record_dict.items(): row = [QStandardItem(item[0]), QStandardItem(item[1])] print(item, row) self.model_attr.appendRow(row) self.table_file.setModel(self.model_attr) self.table_file.resizeColumnsToContents() def tree_file_dclick(self, index): # Двойной клик объекта в дереве файлов info = self.model_file.fileInfo(index) record_dict = ZSSRecord(info).getDict() if record_dict['isFile']: self.action_file_open() def tree_file_rclick(self, position): # Правый клик объекта в дереве файлов self.cmenu_tree_file.exec_( self.tree_file.viewport().mapToGlobal(position)) # Дерево файлов - действия def action_file_open(self): index = self.tree_file.currentIndex() path = self.model_file.filePath(index) try: os.startfile(path) except: print('Не удалось открыть объект') def action_file_del(self): index = self.tree_file.currentIndex() path = self.model_file.filePath(index) try: shutil.rmtree(path) except: try: os.remove(path) except: print('Не удалось удалить объект') def action_new_doc(self): index = self.tree_file.currentIndex() path = self.model_file.filePath(index) info = self.model_file.fileInfo(index) record = ZSSRecordDocument(info) self.zss.new_doc(record.getDict())
class FileManager(QWidget): def __init__(self, parent): QWidget.__init__(self) self.parent = parent self.name = 'File Manager' self.port = '9080' self.server = None drives = win32api.GetLogicalDriveStrings().split('\\\000')[:-1] self.logical_drives = drives + [d+'/' for d in drives] # create file manager tab self.file_manager_layout = QGridLayout(self) # create left manager (PC) self.left_up_btn = QPushButton() self.left_up_btn.setIcon(QIcon('images/up_btn.png')) self.left_up_btn.setFixedWidth(25) self.file_manager_layout.addWidget(self.left_up_btn, 0, 0, 1, 1) self.left_dir_path = QLineEdit(self.parent.expanduser_dir) self.file_manager_layout.addWidget(self.left_dir_path, 0, 1, 1, 8) self.left_go_to_btn = QPushButton() self.left_go_to_btn.setIcon(QIcon('images/right_btn.png')) self.left_go_to_btn.setFixedWidth(25) self.file_manager_layout.addWidget(self.left_go_to_btn, 0, 9, 1, 1) self.lefttableview = QTableView() self.lefttableview.setSelectionBehavior(QTableView.SelectRows) self.lefttableview.verticalHeader().hide() self.lefttableview.setShowGrid(False) self.lefttableview.contextMenuEvent = lambda event: self.left_context(event) self.left_file_model = QFileSystemModel() self.left_file_model.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) self.left_file_model.setRootPath(self.parent.expanduser_dir) self.left_file_model_path = self.parent.expanduser_dir self.lefttableview.setModel(self.left_file_model) self.lefttableview.setColumnWidth(0, 150) self.lefttableview.setRootIndex(self.left_file_model.index(self.parent.expanduser_dir)) self.file_manager_layout.addWidget(self.lefttableview, 1, 0, 5, 10) # central buttons self.download_file_from_device_btn = QPushButton() self.download_file_from_device_btn.setIcon(QIcon('images/left_btn.png')) self.download_file_from_device_btn.setFixedWidth(30) self.download_file_from_device_btn.setEnabled(False) self.upload_file_to_device_btn = QPushButton() self.upload_file_to_device_btn.setIcon(QIcon('images/right_btn.png')) self.upload_file_to_device_btn.setFixedWidth(30) self.upload_file_to_device_btn.setEnabled(False) self.delete_file_btn = QPushButton() self.delete_file_btn.setIcon(QIcon('images/delete_btn.png')) self.delete_file_btn.setFixedWidth(30) self.file_manager_layout.addWidget(self.download_file_from_device_btn, 3, 10, 1, 1) self.file_manager_layout.addWidget(self.delete_file_btn, 4, 10, 1, 1) # create right manager (Device) self.right_up_btn = QPushButton() self.right_up_btn.setIcon(QIcon('images/up_btn.png')) self.right_up_btn.setFixedWidth(25) self.right_up_btn.setEnabled(False) self.file_manager_layout.addWidget(self.right_up_btn, 0, 11, 1, 1) self.add_folder_btn = QPushButton() self.add_folder_btn.setIcon(QIcon('images/folder_add.png')) self.add_folder_btn.setFixedWidth(25) self.add_folder_btn.setToolTip(_('Add new folder')) self.add_folder_btn.setEnabled(False) self.file_manager_layout.addWidget(self.add_folder_btn, 0, 12, 1, 1) self.right_dir_path = QLineEdit() self.file_manager_layout.addWidget(self.right_dir_path, 0, 13, 1, 7) self.right_update_btn = QPushButton() self.right_update_btn.setIcon(QIcon('images/update.png')) self.right_update_btn.setFixedWidth(25) self.file_manager_layout.addWidget(self.right_update_btn, 0, 20, 1, 1) self.righttableview = QTableView() self.righttableview.setSelectionBehavior(QTableView.SelectRows) self.righttableview.contextMenuEvent = lambda event: self.right_context(event) self.righttableview.verticalHeader().hide() self.righttableview.setShowGrid(False) self.right_file_model = QStandardItemModel() self.right_file_model_path = [] self.right_active_dir = None self.righttableview.setModel(self.right_file_model) self.file_manager_layout.addWidget(self.righttableview, 1, 11, 5, 10) # auto sync self.timer = QTimer() self.timer.setInterval(10000) self.file_models_auto_sync = QCheckBox(_('Auto sync')) self.left_file_model_auto_sync_label = QLineEdit() self.left_file_model_auto_sync_label.setReadOnly(True) self.right_file_model_auto_sync_label = QLineEdit() self.right_file_model_auto_sync_label.setReadOnly(True) self.file_manager_layout.addWidget(self.file_models_auto_sync, 6, 9, 1, 3, alignment=Qt.AlignCenter) self.file_manager_layout.addWidget(self.left_file_model_auto_sync_label, 6, 0, 1, 9) self.file_manager_layout.addWidget(self.right_file_model_auto_sync_label, 6, 12, 1, 9) self.timer.timeout.connect(lambda: self.check_device_sync()) self.lefttableview.clicked.connect(lambda idx: self.left_file_model_clicked(idx)) self.lefttableview.doubleClicked.connect(lambda idx: self.left_file_model_doubleclicked(idx)) self.left_up_btn.clicked.connect(lambda: self.left_file_model_up(self.left_file_model.index(self.left_dir_path.text()))) self.left_go_to_btn.clicked.connect(lambda: self.left_file_model_go_to_dir()) self.right_update_btn.clicked.connect(lambda: self.right_file_model_update()) self.righttableview.doubleClicked.connect(lambda idx: self.right_file_model_doubleclicked(idx)) self.right_up_btn.clicked.connect(lambda: self.right_file_model_up()) self.add_folder_btn.clicked.connect(lambda: self.right_file_model_add_folder()) self.righttableview.clicked.connect(lambda idx: self.right_file_model_clicked(idx)) self.download_file_from_device_btn.clicked.connect(lambda: self.download_file_from_device()) self.upload_file_to_device_btn.clicked.connect(lambda: self.upload_file_to_device()) self.delete_file_btn.clicked.connect(lambda: self.delete_file_from_file_model()) self.parent.settings_widget.signal_ip_changed.connect(lambda ip: self.change_ip(ip)) self.parent.signal_language_changed.connect(lambda: self.retranslate()) def retranslate(self): self.file_models_auto_sync.setText(_('Auto sync')) self.right_file_model.setHorizontalHeaderLabels([_('Name'), _('Size'), _('Changed date')]) def change_ip(self, ip): self.server = ':'.join([ip, self.port]) self.right_file_model_path = [] self.right_file_model.clear() def left_file_model_clicked(self, idx): if os.path.isfile(self.left_file_model.filePath(idx)) and self.parent.geoshark_widget.device_on_connect: self.upload_file_to_device_btn.setEnabled(True) else: self.upload_file_to_device_btn.setEnabled(False) def left_file_model_doubleclicked(self, idx): self.left_up_btn.setEnabled(True) fileinfo = self.left_file_model.fileInfo(idx) if fileinfo.isDir(): self.lefttableview.setRootIndex(idx) self.left_dir_path.setText(self.left_file_model.filePath(idx)) self.left_file_model_path = self.left_file_model.filePath(idx) def left_file_model_up(self, idx): self.upload_file_to_device_btn.setEnabled(False) if self.left_dir_path.text() in self.logical_drives: self.left_file_model = QFileSystemModel() self.left_file_model.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) self.left_file_model.setRootPath('') self.lefttableview.setModel(self.left_file_model) self.left_dir_path.setText('My computer') self.left_up_btn.setEnabled(False) else: fileinfo = self.left_file_model.fileInfo(idx) dir = fileinfo.dir() self.left_dir_path.setText(dir.path()) self.left_file_model_path = dir.path() self.lefttableview.setRootIndex(self.left_file_model.index(dir.absolutePath())) def left_file_model_go_to_dir(self): if os.path.isdir(self.left_dir_path.text()): self.left_file_model_path = self.left_dir_path.text() self.left_up_btn.setEnabled(True) self.upload_file_to_device_btn.setEnabled(False) self.left_file_model.setRootPath(self.left_dir_path.text()) self.lefttableview.setRootIndex(self.left_file_model.index(self.left_dir_path.text())) def right_file_model_update(self): if not self.parent.geoshark_widget.device_on_connect: return url = 'http://{}/active_dir'.format(self.server) try: res = requests.get(url, timeout=5) if res.ok: self.right_active_dir = res.text except requests.exceptions.RequestException: pass file_list = self.get_folder_list() if file_list is None: return self.fill_right_file_model(file_list) self.download_file_from_device_btn.setEnabled(False) def get_folder_list(self, folder_path=None): if self.server is None: return if folder_path is None: folder_path = '/'.join(self.right_file_model_path) url = 'http://{}/data/{}'.format(self.server, folder_path) try: res = requests.get(url, timeout=1) except requests.exceptions.RequestException: show_error(_('GeoShark error'), _('GeoShark is not responding.')) return if res.ok: res = res.json() return res else: return None def check_device_sync(self): pc_path = self.left_file_model_auto_sync_label.text() device_path = self.right_file_model_auto_sync_label.text() if self.file_models_auto_sync.isChecked() and pc_path != '' and device_path != '': file_list = self.get_folder_list(self.right_file_model_auto_sync_label.text()) left_list_of_files = os.listdir(self.left_file_model_auto_sync_label.text()) for f in file_list: if f['name'] not in left_list_of_files or os.path.getsize('{}/{}'.format(pc_path, f['name'])) != f['size']: self.download_file_from_device(device_path='{}/{}'.format(device_path, f['name']), pc_path=pc_path) def fill_right_file_model(self, directory): self.add_folder_btn.setEnabled(True) if len(self.right_file_model_path) < 1: self.right_up_btn.setEnabled(False) else: self.right_up_btn.setEnabled(True) self.add_folder_btn.setEnabled(False) self.right_file_model.removeRows(0, self.right_file_model.rowCount()) self.right_dir_path.setText('/'.join(self.right_file_model_path)) self.right_file_model.setHorizontalHeaderLabels([_('Name'), _('Size'), _('Changed date')]) for row, instance in enumerate(directory): if instance['name'] == self.right_active_dir: image = QIcon('images/directory_active.png') else: image = QIcon('images/{}.png'.format(instance['type'])) item = QStandardItem(image, instance['name']) item.setData(instance['type'], 5) item.setEditable(False) self.right_file_model.setItem(row, 0, item) item = QStandardItem(str(instance['size'])) item.setEditable(False) self.right_file_model.setItem(row, 1, item) item = QStandardItem(str(datetime.datetime.fromtimestamp(instance['changed']).strftime('%d.%m.%Y %H:%M'))) item.setEditable(False) self.right_file_model.setItem(row, 2, item) self.righttableview.setColumnWidth(0, max(150, self.righttableview.columnWidth(0))) def left_context(self, event): context_menu = {} index = self.lefttableview.indexAt(event.pos()) if index.row() == -1: return context_menu[_('Set active directory')] = lambda: self.set_pc_active_directory(self.left_file_model.filePath(index)) context_menu[_('Remove element')] = lambda: self.delete_file_from_file_model(index) if not self.left_file_model.isDir(index): del context_menu[_('Set active directory')] menu = QMenu() actions = [QAction(a) for a in context_menu.keys()] menu.addActions(actions) action = menu.exec_(event.globalPos()) if action: context_menu[action.text()]() def set_pc_active_directory(self, path): self.left_file_model_auto_sync_label.setText(path) self.parent.settings_widget.left_folder_tracked.setText(path) def right_context(self, event): context_menu = {} index = self.righttableview.indexAt(event.pos()) if index.row() == -1: return item = self.right_file_model.itemFromIndex(index) item_row = item.row() context_menu[_('Set active directory')] = lambda: self.set_active_directory(item) context_menu[_('Remove element')] = lambda: self.delete_file_from_file_model(index) if self.right_file_model.item(item_row, 0).data(5) != 'directory': del context_menu[_('Set active directory')] menu = QMenu() actions = [QAction(a) for a in context_menu.keys()] menu.addActions(actions) action = menu.exec_(event.globalPos()) if action: context_menu[action.text()]() def set_active_directory(self, item): if not self.parent.geoshark_widget.device_on_connect: return dirname = item.text() url = 'http://{}/active_dir'.format(self.server) try: res = requests.post(url=url, data=dirname, timeout=5) except requests.exceptions.RequestException: show_error(_('GeoShark error'), _('Can not set active directory.\nGeoShark is not responding.')) return if res.ok: self.right_file_model_update() self.set_active_path(dirname) elif res.status_code == 400: show_error(_('GeoShark error'), _('Request declined - request body specifies invalid path.')) return elif res.status_code == 409: show_error(_('GeoShark error'), _('Request declined - switching active directory is forbidden during active session.')) return else: print(res.status_code) return def set_active_path(self, dirname): path = '/'.join(self.right_file_model_path + [dirname]) self.parent.settings_widget.right_folder_tracked.setText(path) self.right_file_model_auto_sync_label.setText(path) def right_file_model_clicked(self, idx): if not self.parent.geoshark_widget.device_on_connect: return if self.right_file_model.item(idx.row(), 0).data(5) == 'file': self.download_file_from_device_btn.setEnabled(True) else: self.download_file_from_device_btn.setEnabled(False) def right_file_model_doubleclicked(self, idx): if not self.parent.geoshark_widget.device_on_connect: return model_path = '/'.join(self.right_file_model_path) idx_name = self.right_file_model.item(idx.row(), 0).text() if model_path != '': dir = '{}/{}'.format(model_path, idx_name) else: dir = '{}'.format(idx_name) file_list = self.get_folder_list(dir) if file_list is None: return self.right_file_model_path = dir.split('/') self.fill_right_file_model(file_list) def right_file_model_up(self): if not self.parent.geoshark_widget.device_on_connect: return self.download_file_from_device_btn.setEnabled(False) up_dir = '/'.join(self.right_file_model_path[:-1]) file_list = self.get_folder_list(up_dir) if file_list is None: return if up_dir == '': self.right_file_model_path = [] else: self.right_file_model_path = up_dir.split('/') self.fill_right_file_model(file_list) def right_file_model_add_folder(self): if not self.parent.geoshark_widget.device_on_connect: return row = self.right_file_model.rowCount() item = QStandardItem(QIcon('images/folder.png'), 'New Directory') item.setData('directory', 5) item.setEditable(True) self.right_file_model.setItem(row, 0, item) item = QStandardItem(str(0.0)) item.setEditable(False) self.right_file_model.setItem(row, 1, item) item = QStandardItem(str(datetime.datetime.today().strftime('%d.%m.%Y %H:%M'))) item.setEditable(False) self.right_file_model.setItem(row, 2, item) def download_file_from_device(self, device_path=None, pc_path=None): if not self.parent.geoshark_widget.device_on_connect or self.server is None: return if not device_path: fileName = self.find_selected_idx() if fileName: fileName = fileName.data() device_path = '/'.join(self.right_file_model_path + [fileName]) else: return right_file_model_filename = device_path.split('/')[-1] save_to_file = '{}/{}'.format(self.left_file_model_path, right_file_model_filename) \ if not pc_path else '{}/{}'.format(pc_path, right_file_model_filename) if os.path.isfile(save_to_file): answer = show_warning_yes_no(_('File warning'), _('There is a file with the same name in PC.\n' 'Do you want to rewrite <b>{}</b>?'.format(right_file_model_filename))) if answer == QMessageBox.No: return url = 'http://{}/data/{}'.format(self.server, device_path) try: b = bytearray() res = requests.get(url, timeout=5, stream=True) if res.ok: progress = QProgressBar() progress.setFormat(right_file_model_filename) self.file_manager_layout.addWidget(progress, 6, 12, 1, 9) total_length = int(res.headers.get('content-length')) len_b = 0 for chunk in tee_to_bytearray(res, b): len_b += len(chunk) progress.setValue((len_b/total_length)*99) QApplication.processEvents() else: return except: self.file_manager_layout.addWidget(self.right_file_model_auto_sync_label, 6, 12, 1, 9) show_error(_('GeoShark error'), _('GeoShark is not responding.')) return if res.ok: progress.setValue(100) with open(save_to_file, 'wb') as file: file.write(b) for i in reversed(range(self.file_manager_layout.count())): if isinstance(self.file_manager_layout.itemAt(i).widget(), QProgressBar): self.file_manager_layout.itemAt(i).widget().setParent(None) self.file_manager_layout.addWidget(self.right_file_model_auto_sync_label, 6, 12, 1, 9) def upload_file_to_device(self): if not self.parent.geoshark_widget.device_on_connect or self.server is None: return file = self.left_file_model.filePath(self.lefttableview.currentIndex()) filename = file.split('/')[-1] url = 'http://{}/data/{}'.format(self.server, '/'.join(self.right_file_model_path)) filesize = os.path.getsize(file) if filesize == 0: show_error(_('File error'), _('File size must be non zero.')) return progress = ProgressBar(text=_('Upload File Into GeoShark'), window_title=_('Upload file to GeoShark')) encoder = MultipartEncoder( fields={'upload_file': (filename, open(file, 'rb'))} # added mime-type here ) data = MultipartEncoderMonitor(encoder, lambda monitor: progress.update((monitor.bytes_read/filesize)*99)) try: res = requests.post(url, data=data, headers={'Content-Type': encoder.content_type}, timeout=5) except requests.exceptions.RequestException: progress.close() show_error(_('GeoShark error'), _('GeoShark is not responding.')) return if res.ok: progress.update(100) self.right_file_model_update() def delete_file_from_file_model(self, index=None): selected = self.find_selected_idx() if index is None and selected is None: return if index is None: index = selected model = index.model() index_row = index.row() path = model.filePath(index) if hasattr(model, 'filePath') else model.index(index_row, 0).data() answer = show_warning_yes_no(_('Remove File warning'), _('Do you really want to remove:\n{}').format(path)) if answer == QMessageBox.No: return if isinstance(model, QFileSystemModel): model.remove(index) elif isinstance(model, QStandardItemModel): if not self.parent.geoshark_widget.device_on_connect or self.server is None: return filename = self.right_file_model.item(index.row(), 0).text() path = '/'.join(self.right_file_model_path + [filename]) url = 'http://{}/data/{}'.format(self.server, path) try: res = requests.delete(url) except requests.exceptions.RequestException: show_error(_('GeoShark error'), _('GeoShark is not responding.')) return if res.ok: self.right_file_model_update() elif res.status_code == 400: self.right_file_model.removeRow(index.row()) elif res.status_code == 409: show_error(_('GeoShark error'), _('Request declined - directory is the part of active session working directory.')) return def find_selected_idx(self): left_indexes = self.lefttableview.selectedIndexes() right_indexes = self.righttableview.selectedIndexes() if len(left_indexes) == 0 and len(right_indexes) == 0: return None index = left_indexes[0] if len(left_indexes) > len(right_indexes) else right_indexes[0] return index def save_file_models_folder(self): self.left_file_model_auto_sync_label.setText(self.parent.settings_widget.left_folder_tracked.text()) self.right_file_model_auto_sync_label.setText(self.parent.settings_widget.right_folder_tracked.text())
class Dialog_ImageFolder(): def __init__(self, parent, title, init_path): self.w = QDialog(parent) self.parent = parent self.left = 300 self.top = 300 self.width = 600 self.height = 400 self.title = title self.dirModel = QFileSystemModel() self.dirModel.setRootPath(init_path) self.dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.treeview = QTreeView() self.treeview.setModel(self.dirModel) self.treeview.setRootIndex(self.dirModel.index("")) self.treeview.clicked.connect(self.on_clicked) #--- Hide All Header Sections Except First ---- header = self.treeview.header() for sec in range(1, header.count()): header.setSectionHidden(sec, True) #--- ---- ---- ---- ---- ---- ---- ---- ---- -- focus_index = self.dirModel.index(init_path) self.treeview.setCurrentIndex(focus_index) self.current_row_changed() self.listview = QListView() self.listview.setViewMode(QListView.IconMode) self.listview.setIconSize(QSize(192, 192)) targetfiles1 = glob.glob(os.path.join(init_path, '*.png')) targetfiles2 = glob.glob(os.path.join(init_path, '*.tif')) targetfiles3 = glob.glob(os.path.join(init_path, '*.tiff')) targetfiles = targetfiles1 + targetfiles2 + targetfiles3 lm = _MyListModel(targetfiles, self.parent) self.listview.setModel(lm) self.sub_layout = QHBoxLayout() self.sub_layout.addWidget(self.treeview) self.sub_layout.addWidget(self.listview) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Open | QDialogButtonBox.Cancel) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.main_layout = QVBoxLayout() self.main_layout.addLayout(self.sub_layout) self.main_layout.addWidget(self.buttonBox) self.w.setGeometry(self.left, self.top, self.width, self.height) self.w.setWindowTitle(self.title) self.w.setWindowIcon(QIcon(os.path.join(icon_dir, 'Mojo2_16.png'))) self.w.setLayout(self.main_layout) def current_row_changed(self): index = self.treeview.currentIndex() self.treeview.scrollTo(index, QAbstractItemView.EnsureVisible) self.treeview.resizeColumnToContents(0) def on_clicked(self, index): path = self.dirModel.fileInfo(index).absoluteFilePath() targetfiles1 = glob.glob(os.path.join(path, '*.png')) targetfiles2 = glob.glob(os.path.join(path, '*.tif')) targetfiles3 = glob.glob(os.path.join(path, '*.tiff')) targetfiles = targetfiles1 + targetfiles2 + targetfiles3 lm = _MyListModel(targetfiles, self.parent) self.listview.setModel(lm) def accept(self): index = self.treeview.currentIndex() self.newdir = self.dirModel.filePath(index) self.w.done(1) def reject(self): self.w.done(0) def GetValue(self): index = self.treeview.currentIndex() self.newdir = self.dirModel.filePath(index) return self.newdir
class FileManager(QWidget, _HalWidgetBase): def __init__(self, parent=None): super(FileManager, self).__init__(parent) self.title = 'PyQt5 file system view - pythonspot.com' self.left = 10 self.top = 10 self.width = 640 self.height = 480 self.default_path = (os.path.join(os.path.expanduser('~'), 'linuxcnc/nc_files/examples')) self.user_path = (os.path.join('/media')) self.currentPath = None self.EXT = INFO.PROGRAM_FILTERS_EXTENSIONS self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.model = QFileSystemModel() self.model.setRootPath(QDir.currentPath()) self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files) self.model.setNameFilterDisables(False) self.model.setNameFilters(self.EXT) self.list = QListView() self.list.setModel(self.model) self.updateDirectoryView(self.default_path) self.list.setWindowTitle("Dir View") self.list.resize(640, 480) self.list.clicked[QModelIndex].connect(self.clicked) self.list.activated.connect(self._getPathActivated) #self.list.currentChanged = self.currentChanged self.list.setAlternatingRowColors(True) self.cb = QComboBox() self.cb.currentTextChanged.connect(self.filterChanged) self.cb.addItems(self.EXT) #self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button = QPushButton() self.button.setText('Media') self.button.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button.setToolTip('Jump to Media directory') self.button.clicked.connect(self.onMediaClicked) self.button2 = QPushButton() self.button2.setText('User') self.button2.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button2.setToolTip('Jump to linuxcnc directory') self.button2.clicked.connect(self.onUserClicked) hbox = QHBoxLayout() hbox.addWidget(self.button) hbox.addWidget(self.button2) hbox.addWidget(self.cb) windowLayout = QVBoxLayout() windowLayout.addWidget(self.list) windowLayout.addLayout(hbox) self.setLayout(windowLayout) self.show() # this could return the current/previous selected as it's selected. # need to uncomment monkey patch of self.list.currentChanged above # so far this is not needed def currentChanged(self,c,p): dir_path = self.model.filePath(c) print('-> ',dir_path) def updateDirectoryView(self, path): self.list.setRootIndex(self.model.setRootPath(path)) def filterChanged(self, text): self.model.setNameFilters([text]) def clicked(self, index): # the signal passes the index of the clicked item dir_path = self.model.filePath(index) if self.model.fileInfo(index).isFile(): self.currentPath = dir_path return root_index = self.model.setRootPath(dir_path) self.list.setRootIndex(root_index) def onMediaClicked(self): self.updateDirectoryView(self.user_path) def onUserClicked(self): self.updateDirectoryView(self.default_path) def select_row(self, style): style = style.lower() selectionModel = self.list.selectionModel() row = selectionModel.currentIndex().row() self.rows = self.model.rowCount(self.list.rootIndex()) if style == 'last': row = self.rows elif style == 'up': if row > 0: row -= 1 else: row = 0 elif style == 'down': if row < self.rows: row += 1 else: row = self.rows else: return top = self.model.index(row, 0, self.list.rootIndex()) selectionModel.setCurrentIndex(top, QItemSelectionModel.Select | QItemSelectionModel.Rows) selection = QItemSelection(top, top) selectionModel.clearSelection() selectionModel.select(selection, QItemSelectionModel.Select) # returns the current highlighted (selected) path as well as # whether it's a file or not. def getCurrentSelected(self): selectionModel = self.list.selectionModel() index = selectionModel.currentIndex() dir_path = self.model.filePath(index) if self.model.fileInfo(index).isFile(): return (dir_path, True) else: return (dir_path, False) def _hal_init(self): if self.PREFS_: last_path = self.PREFS_.getpref('last_loaded_directory', self.default_path, str, 'BOOK_KEEPING') self.updateDirectoryView(last_path) LOG.debug("lAST FILE PATH: {}".format(last_path)) else: LOG.debug("lAST FILE PATH: {}".format(self.default_path)) self.updateDirectoryView(self.default_path) # get current selection and update the path # then if the path is good load it into linuxcnc # record it in the preference file if available def _getPathActivated(self): row = self.list.selectionModel().currentIndex() self.clicked(row) fname = self.currentPath if fname is None: return if fname: self.load(fname) # this can be class patched to do something else def load(self, fname=None): if fname is None: self._getPathActivated() return self.recordBookKeeping() ACTION.OPEN_PROGRAM(fname) STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME') # this can be class patched to do something else def recordBookKeeping(self): fname = self.currentPath if fname is None: return if self.PREFS_: self.PREFS_.putpref('last_loaded_directory', self.model.rootPath(), str, 'BOOK_KEEPING') self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING') # moves the selection up # used with MPG scrolling def up(self): self.select_row('up') # moves the selection down # used with MPG scrolling def down(self): self.select_row('down')
class FileManager(QWidget, _HalWidgetBase): def __init__(self, parent=None): super(FileManager, self).__init__(parent) self.title = 'Qtvcp File System View' self.left = 10 self.top = 10 self.width = 640 self.height = 480 self.media_path = (os.path.join(os.path.expanduser('~'), 'linuxcnc/nc_files')) user = os.path.split(os.path.expanduser('~'))[-1] self.user_path = (os.path.join('/media', user)) self.currentPath = None self.currentFolder = None self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) pasteBox = QHBoxLayout() self.textLine = QLineEdit() self.textLine.setToolTip('Current Director/selected File') self.pasteButton = QToolButton() self.pasteButton.setEnabled(False) self.pasteButton.setText('Paste') self.pasteButton.setToolTip( 'Copy file from copy path to current directory/file') self.pasteButton.clicked.connect(self.paste) self.pasteButton.hide() pasteBox.addWidget(self.textLine) pasteBox.addWidget(self.pasteButton) self.copyBox = QFrame() hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) self.copyLine = QLineEdit() self.copyLine.setToolTip('File path to copy from, when pasting') self.copyButton = QToolButton() self.copyButton.setText('Copy') self.copyButton.setToolTip('Record current file as copy path') self.copyButton.clicked.connect(self.recordCopyPath) hbox.addWidget(self.copyButton) hbox.addWidget(self.copyLine) self.copyBox.setLayout(hbox) self.copyBox.hide() self.model = QFileSystemModel() self.model.setRootPath(QDir.currentPath()) self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files) self.model.setNameFilterDisables(False) self.model.rootPathChanged.connect(self.folderChanged) self.list = QListView() self.list.setModel(self.model) self.updateDirectoryView(self.media_path) self.list.resize(640, 480) self.list.clicked[QModelIndex].connect(self.listClicked) self.list.activated.connect(self._getPathActivated) self.list.setAlternatingRowColors(True) self.cb = QComboBox() self.cb.currentIndexChanged.connect(self.filterChanged) self.fillCombobox(INFO.PROGRAM_FILTERS_EXTENSIONS) self.cb.setMinimumHeight(30) self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button2 = QToolButton() self.button2.setText('Media') self.button2.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button2.setMinimumSize(60, 30) self.button2.setToolTip('Jump to Media directory') self.button2.clicked.connect(self.onJumpClicked) SettingMenu = QMenu(self) self.settingMenu = SettingMenu for i in ('Media', 'User'): axisButton = QAction(QIcon.fromTheme('user-home'), i, self) # weird lambda i=i to work around 'function closure' axisButton.triggered.connect( lambda state, i=i: self.jumpTriggered(i)) SettingMenu.addAction(axisButton) self.button2.setMenu(SettingMenu) self.button3 = QToolButton() self.button3.setText('Add Jump') self.button3.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button3.setMinimumSize(60, 30) self.button3.setToolTip('Add current directory to jump button list') self.button3.clicked.connect(self.onActionClicked) hbox = QHBoxLayout() hbox.addWidget(self.button2) hbox.addWidget(self.button3) hbox.insertStretch(2, stretch=0) hbox.addWidget(self.cb) windowLayout = QVBoxLayout() windowLayout.addLayout(pasteBox) windowLayout.addWidget(self.copyBox) windowLayout.addWidget(self.list) windowLayout.addLayout(hbox) self.setLayout(windowLayout) self.show() def _hal_init(self): if self.PREFS_: last_path = self.PREFS_.getpref('last_loaded_directory', self.media_path, str, 'BOOK_KEEPING') self.updateDirectoryView(last_path) LOG.debug("lAST FILE PATH: {}".format(last_path)) else: LOG.debug("lAST FILE PATH: {}".format(self.media_path)) self.updateDirectoryView(self.media_path) ######################### # callbacks ######################### # add shown text and hidden filter data from the INI def fillCombobox(self, data): for i in data: self.cb.addItem(i[0], i[1]) def folderChanged(self, data): self.currentFolder = data self.textLine.setText(data) def updateDirectoryView(self, path): self.list.setRootIndex(self.model.setRootPath(path)) # retrieve selected filter (it's held as QT.userData) def filterChanged(self, index): userdata = self.cb.itemData(index) self.model.setNameFilters(userdata) def listClicked(self, index): # the signal passes the index of the clicked item dir_path = self.model.filePath(index) if self.model.fileInfo(index).isFile(): self.currentPath = dir_path self.textLine.setText(self.currentPath) return root_index = self.model.setRootPath(dir_path) self.list.setRootIndex(root_index) def onUserClicked(self): self.showUserDir() def onMediaClicked(self): self.showMediaDir() def onJumpClicked(self): data = self.button2.text() if data == 'Media': self.showMediaDir() elif data == 'User': self.showUserDir() else: self.updateDirectoryView(self.button2.text()) def jumpTriggered(self, data): if data == 'Media': self.button2.setText('{}'.format(data)) self.button2.setToolTip('Jump to Media directory') self.showMediaDir() elif data == 'User': self.button2.setText('{}'.format(data)) self.button2.setToolTip('Jump to User directory') self.showUserDir() else: self.button2.setText('{}'.format(data)) self.button2.setToolTip('Jump to directory: {}'.format(data)) self.updateDirectoryView(self.button2.text()) def onActionClicked(self): i = self.currentFolder button = QAction(QIcon.fromTheme('user-home'), i, self) # weird lambda i=i to work around 'function closure' button.triggered.connect(lambda state, i=i: self.jumpTriggered(i)) self.settingMenu.addAction(button) # get current selection and update the path # then if the path is good load it into linuxcnc # record it in the preference file if available def _getPathActivated(self): row = self.list.selectionModel().currentIndex() self.listClicked(row) fname = self.currentPath if fname is None: return if fname: self.load(fname) def recordCopyPath(self): data, isFile = self.getCurrentSelected() if isFile: self.copyLine.setText(os.path.normpath(data)) self.pasteButton.setEnabled(True) else: self.copyLine.setText('') self.pasteButton.setEnabled(False) STATUS.emit('error', OPERATOR_ERROR, 'Can only copy a file, not a folder') def paste(self): res = self.copyFile(self.copyLine.text(), self.textLine.text()) if res: self.copyLine.setText('') self.pasteButton.setEnabled(False) ######################## # helper functions ######################## def showCopyControls(self, state): if state: self.copyBox.show() self.pasteButton.show() else: self.copyBox.hide() self.pasteButton.hide() def showMediaDir(self): self.updateDirectoryView(self.user_path) def showUserDir(self): self.updateDirectoryView(self.media_path) def copyFile(self, s, d): try: shutil.copy(s, d) return True except Exception as e: LOG.error("Copy file error: {}".format(e)) STATUS.emit('error', OPERATOR_ERROR, "Copy file error: {}".format(e)) return False # moves the selection up # used with MPG scrolling def up(self): self.select_row('up') # moves the selection down # used with MPG scrolling def down(self): self.select_row('down') def select_row(self, style='down'): style = style.lower() selectionModel = self.list.selectionModel() row = selectionModel.currentIndex().row() self.rows = self.model.rowCount(self.list.rootIndex()) if style == 'last': row = self.rows elif style == 'up': if row > 0: row -= 1 else: row = 0 elif style == 'down': if row < self.rows: row += 1 else: row = self.rows else: return top = self.model.index(row, 0, self.list.rootIndex()) selectionModel.setCurrentIndex( top, QItemSelectionModel.Select | QItemSelectionModel.Rows) selection = QItemSelection(top, top) selectionModel.clearSelection() selectionModel.select(selection, QItemSelectionModel.Select) # returns the current highlighted (selected) path as well as # whether it's a file or not. def getCurrentSelected(self): selectionModel = self.list.selectionModel() index = selectionModel.currentIndex() dir_path = self.model.filePath(index) if self.model.fileInfo(index).isFile(): return (dir_path, True) else: return (dir_path, False) # This can be class patched to do something else def load(self, fname=None): if fname is None: self._getPathActivated() return self.recordBookKeeping() ACTION.OPEN_PROGRAM(fname) STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME') # This can be class patched to do something else def recordBookKeeping(self): fname = self.currentPath if fname is None: return if self.PREFS_: self.PREFS_.putpref('last_loaded_directory', self.model.rootPath(), str, 'BOOK_KEEPING') self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING')
class MainWin(QMainWindow, Ui_MainWindow): def __init__(self): super(MainWin,self).__init__() self.setupUi(self) self.Login.triggered.connect(self.open_login) self.RGB.triggered.connect(self.open_image_rgb) self.LoginDialog = LoginDialog() self.ImageMainWin = ImageRGB() # 设置TreeWidgets self.trees = [self.YCPGAMETREE, self.YCPCOMPTREE, self.YLANDFILETREE] for tree in self.trees: tree.setContextMenuPolicy(Qt.CustomContextMenu) tree.customContextMenuRequested.connect(self.show_context_menu) tree.header().setMinimumSectionSize(120) self.model = QFileSystemModel() self.RailID = '' self.ylands_path = '' self.rail_user_data = '' self.ycp_game_folder_path = '' self.ycp_comp_folder_path = '' self.yland_folder_path = '' self.key = OpenKey(HKEY_CURRENT_USER, r"Software\Rail\YlandsRail") _value, type = QueryValueEx(self.key, "InstallPath") if _value: self.ylands_path = _value self.rail_user_data = Path.dirname(self.ylands_path) + '\\' + 'rail_user_data\\2000108' self.YCPTAB.currentChanged.connect(self.refresh_tab_qlistwidget) self.GroupBoxTitleDict = {0: 'YCP游戏目录', 1: 'YCP组件目录', 2: 'YLAND文件目录'} self.YCPTAB.setCurrentIndex(0) print(self.OpenDirBtn.clicked) # 打开workshop 后去RailId def open_login(self): self.LoginDialog.LoginRailIDSignel.connect(self.slot_emit) self.LoginDialog.show() def open_image_rgb(self): self.ImageMainWin.show() def slot_emit(self, flag, str): # 获得 rail_id self.RailID = str self.ycp_game_folder_path = self.rail_user_data + '\\' + self.RailID + '\\cloud_storage\\files\\Share\\Games' self.ycp_comp_folder_path = self.rail_user_data + '\\' + self.RailID + '\\cloud_storage\\files\\Share\\Compositions' self.yland_folder_path = self.rail_user_data + '\\' + self.RailID + '\\cloud_storage\\files\\Scenarios' if not Path.exists(self.ycp_game_folder_path): makedirs(self.ycp_game_folder_path) if not Path.exists(self.ycp_comp_folder_path): makedirs(self.ycp_comp_folder_path) if not Path.exists(self.yland_folder_path): makedirs(self.yland_folder_path) self.YCPTAB.setEnabled(True) self.YCPTAB.setCurrentIndex(0) self.refresh_tab_qlistwidget(0) self.setAcceptDrops(True) def refresh_tab_qlistwidget(self, index): if self.RailID != '': self.OpenDirBtn.setEnabled(True) if index == 0: self.YCPGAMETREE.setEnabled(True) self.refresh_path(index, self.ycp_game_folder_path) self.model.setRootPath(self.ycp_game_folder_path) self.YCPGAMETREE.setModel(self.model) self.YCPGAMETREE.setRootIndex(self.model.index(self.ycp_game_folder_path)) elif index == 1: self.YCPCOMPTREE.setEnabled(True) self.refresh_path(index, self.ycp_comp_folder_path) self.model.setRootPath(self.ycp_comp_folder_path) self.YCPCOMPTREE.setModel(self.model) self.YCPCOMPTREE.setRootIndex(self.model.index(self.ycp_comp_folder_path)) else: self.YLANDFILETREE.setEnabled(True) self.refresh_path(index, self.yland_folder_path) self.model.setRootPath(self.yland_folder_path) self.YLANDFILETREE.setModel(self.model) self.YLANDFILETREE.setRootIndex(self.model.index(self.yland_folder_path)) def refresh_path(self, index, path): self.files_count(path) self.frame.findChild(QGroupBox, 'groupBox').setTitle(self.GroupBoxTitleDict[index]) self.PathTxt.setText(path) if MainWin.isconnected(self.OpenDirBtn, 'clicked()'): self.OpenDirBtn.disconnect() self.OpenDirBtn.clicked.connect(lambda: self.open_dir(path, index)) #TODO 通过背景颜色,显示文件被使用的状态 def open_dir(self, path, index): # QFileDialog.getExistingDirectory(self,"浏览"+ self.GroupBoxTitleDict[index], path, QFileDialog.ShowDirsOnly) QFileDialog.getOpenFileNames(self, "浏览" + self.GroupBoxTitleDict[index], path, "All Files (*);;Text Files (*.txt)") def files_count(self, path): count = 0 for root, dirs, files in walk(path): for each in files: file = Path.splitext(each) filename, type = file if type != '.txt': count += 1 self.statusbar.showMessage("文件数:" + str(count)) @staticmethod def isconnected(obj, name): """判断信号是否连接 :param obj: 对象 :param name: 信号名,如 clicked() """ index = obj.metaObject().indexOfMethod(name) if index > -1: method = obj.metaObject().method(index) if method: return obj.isSignalConnected(method) return False def show_context_menu(self, pos): sender = self.sender() row_index = sender.indexAt(pos).row() menu = QMenu() cpy = menu.addAction('复制') cpy.triggered.connect(lambda: self.copy_selected(sender.currentIndex())) rmfile = menu.addAction('删除') rmfile.triggered.connect(lambda: self.remove_selected_file(sender.currentIndex())) menu.exec_(QCursor.pos()) def copy_selected(self, index): filename = self.model.fileName(index) filepath = self.model.filePath(index) data = QMimeData() url = QUrl.fromLocalFile(filepath) clipboard = QApplication.clipboard() data.setUrls([url]) clipboard.setMimeData(data) def remove_selected_file(self, index): filename = self.model.fileName(index) filepath = self.model.filePath(index) if not self.model.fileInfo(index).isDir(): msgBox = QMessageBox() msgBox.setText("确定删除文件:" + filename + "?") msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) ret = msgBox.exec_() if ret == QMessageBox.Ok: self.model.remove(index) else: return def dragEnterEvent(self, event): if event.mimeData().hasUrls: filetempname = event.mimeData().urls()[0].fileName() filename, extension = Path.splitext(filetempname) if self.YCPTAB.currentIndex() == 0 or self.YCPTAB.currentIndex() == 1: if extension == '.ycp': event.accept() # clipboard = QApplication.clipboard() # clipboard.clear() # clipboard.setMimeData(event.mimeData()) else: msgBox = QMessageBox() msgBox.setText("只能拖放.ycp后缀文件") ret = msgBox.exec_() event.ignore() return elif self.YCPTAB.currentIndex() == 2: if extension == '.yland': event.accept() # clipboard = QApplication.clipboard() # clipboard.clear() # clipboard.setMimeData(event.mimeData()) else: msgBox = QMessageBox() msgBox.setText("只能拖放.yland后缀文件") ret = msgBox.exec_() event.ignore() return def dragMoveEvent(self, event): if event.mimeData().hasUrls: try: event.setDropAction(Qt.CopyAction) except Exception as e: print(e) event.accept() else: event.ignore() def dropEvent(self, event): try: if event.mimeData().hasUrls: event.setDropAction(Qt.CopyAction) event.accept() filepath = event.mimeData().urls()[0] filename = filepath.fileName() if self.YCPTAB.currentIndex() == 0: self.copy_file(filepath.url().replace("file:///", ""), Path.join(self.ycp_game_folder_path, filename)) elif self.YCPTAB.currentIndex() == 1: self.copy_file(filepath.url().replace("file:///", ""), Path.join(self.ycp_comp_folder_path, filename)) else: self.copy_file(filepath.url().replace("file:///", ""), Path.join(self.yland_folder_path, filename)) else: event.ignore() except Exception as e: print(e) def copy_file(self,srcfle, dstfile): newdstfile = dstfile if not Path.isfile(srcfle): print("$%s not exist!" % (srcfle)) else: fpath, ftempname = Path.split(dstfile) if not Path.exists(fpath): makedirs(fpath) elif Path.exists(dstfile): filename, extension = Path.splitext(ftempname) newdstfile = Path.join(fpath, filename + "copybyylandsbox" + extension) copyfile(srcfle, newdstfile)
class App(QWidget): def __init__(self): super().__init__() self.left = 100 self.top = 100 self.width = 1200 self.height = 720 self.setWindowTitle('Mammogram Prediction') self.setGeometry(self.left, self.top, self.width, self.height) self.initUI() def initUI(self): # Widget for showing picture. The QLabel gets a Pixmap added to it to show picture self.picture_name_label = QLabel(currently_selected_picture) self.picture_label = QLabel() self.prediction_text = QTextEdit() self.prediction_text.setReadOnly(True) self.model_label = QLabel() self.init_picture_and_predictions() self.resized_picture = self.picture.scaled(299, 299, Qt.KeepAspectRatio, Qt.FastTransformation) self.picture_label.setPixmap(self.resized_picture) self.picture_label.setMinimumWidth(299) self.picture_label.setMinimumHeight(299) self.picture_label.setContentsMargins(0, 19, 0, 0) # Tree and List view for file directory overview of pictures self.picture_directory_label = QLabel('Select a Picture:') picture_dir_path = 'pictures\\' picture_file_path = 'pictures\\' self.treeview_picture = QTreeView() self.listview_picture = QListView() self.dirModel_picture = QFileSystemModel() self.dirModel_picture.setRootPath(picture_dir_path) self.dirModel_picture.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.fileModel_picture = QFileSystemModel() self.fileModel_picture.setRootPath(picture_file_path) # self.fileModel_picture.setFilter(QDir.NoDotAndDotDot | QDir.Files) self.treeview_picture.setModel(self.dirModel_picture) self.listview_picture.setModel(self.fileModel_picture) self.treeview_picture.setRootIndex( self.dirModel_picture.index(picture_dir_path)) self.listview_picture.setRootIndex( self.fileModel_picture.index(picture_file_path)) # self.treeview_picture.setCurrentIndex( self.dirModel_picture.index(0, 0)) self.treeview_picture.clicked.connect( self.on_picture_treeview_clicked) self.listview_picture.clicked.connect( self.on_picture_listview_clicked) self.treeview_picture.setColumnHidden(1, True) self.treeview_picture.setColumnWidth(0, 275) self.treeview_picture.setMinimumWidth(500) self.listview_picture.setMinimumWidth(500) # List view for file directory overview of five label models self.model_directory_label = QLabel('Select a Five Label Model:') model_path = 'trained_five_Models\\' self.listview_model = QListView() self.dirModel_model = QFileSystemModel() self.dirModel_model.setRootPath(model_path) self.dirModel_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.listview_model.setModel(self.dirModel_model) self.listview_model.setRootIndex( self.dirModel_model.index(model_path)) self.listview_model.clicked.connect(self.on_model_listview_clicked) # List view for file directory overview of binary models self.model_binary_directory_label = QLabel( 'Select a Binary Model:') model_binary_path = 'trained_binary_Models\\' self.listview_model_binary = QListView() self.dirModel_model_binary = QFileSystemModel() self.dirModel_model_binary.setRootPath(model_binary_path) self.dirModel_model_binary.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.listview_model_binary.setModel(self.dirModel_model_binary) self.listview_model_binary.setRootIndex( self.dirModel_model_binary.index(model_binary_path)) self.listview_model_binary.setSelectionMode( QAbstractItemView.MultiSelection) self.listview_model_binary.clicked.connect( self.on_model_binary_listview_clicked) # Layout handling. # self.gridlayout = QGridLayout() # self.gridlayout.addWidget(self.model_directory_label, 0, 0) # self.gridlayout.setColumnStretch(-15, -11) # self.gridlayout.addWidget(self.listview_model, 1, 0) # self.gridlayout.addWidget(self.picture_directory_label, 2, 0) # self.gridlayout.addWidget(self.treeview_picture, 3, 0) # # self.gridlayout.addWidget(self.model_binary_directory_label, 0, 1) # self.gridlayout.addWidget(self.listview_model_binary, 1, 1) # self.gridlayout.addWidget(self.listview_picture, 3, 1) # # self.gridlayout.addWidget(self.picture_label, 0, 2) # self.gridlayout.addWidget(self.picture_name_label, 1, 2) # self.gridlayout.addWidget(self.prediction_text, 3, 2) self.vbox = QVBoxLayout() self.vbox_left = QVBoxLayout() self.vbox_right = QVBoxLayout() self.hbox_outer = QHBoxLayout() self.hbox_top = QHBoxLayout() self.hbox_buttom = QHBoxLayout() self.vbox_five_label = QVBoxLayout() self.vbox_binary = QVBoxLayout() self.vbox.addLayout(self.hbox_outer) self.hbox_outer.addLayout(self.vbox_left) self.hbox_outer.addLayout(self.vbox_right) self.vbox_left.addLayout(self.hbox_top) self.hbox_top.addLayout(self.vbox_five_label) self.hbox_top.addLayout(self.vbox_binary) self.vbox_five_label.addWidget(self.model_directory_label) self.vbox_five_label.addWidget(self.listview_model) self.vbox_binary.addWidget(self.model_binary_directory_label) self.vbox_binary.addWidget(self.listview_model_binary) self.vbox_left.addWidget(self.picture_directory_label) self.vbox_left.addLayout(self.hbox_buttom) self.hbox_buttom.addWidget(self.treeview_picture) self.hbox_buttom.addWidget(self.listview_picture) self.vbox_right.addWidget(self.picture_label, alignment=Qt.AlignHCenter) self.vbox_right.addWidget(self.picture_name_label, alignment=Qt.AlignHCenter) self.vbox_right.addWidget(self.model_label, alignment=Qt.AlignHCenter) self.vbox_right.addWidget(self.prediction_text) self.vbox_right.setAlignment(Qt.AlignCenter) self.setLayout(self.vbox) self.sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) self.setSizePolicy(self.sizePolicy) self.show() def init_picture_and_predictions(self): if currently_selected_picture == 'Currently No Image Selected': self.picture = QtGui.QPixmap('GUI/no_image_selected.png') self.prediction_text.setText('') def on_picture_treeview_clicked(self, index): pathof_selected_dir = self.dirModel_picture.fileInfo( index).absoluteFilePath() self.listview_picture.setRootIndex( self.fileModel_picture.setRootPath(pathof_selected_dir)) def on_picture_listview_clicked(self, index): global currently_selected_model global currently_selected_model_name global currently_selected_picture currently_selected_picture = self.fileModel_picture.fileInfo( index).absoluteFilePath() try: Image.open(currently_selected_picture) self.picture_name_label.setText(currently_selected_picture) self.picture_label.setPixmap( QtGui.QPixmap(currently_selected_picture)) except IOError: print('Exception: Chosen file is not a picture') # Checks if the selected picture has size 299 image_in = cv2.imread(currently_selected_picture) size = image_in.shape[:2] if size[0] == 299: if currently_selected_model is not None: for model in currently_selected_model: new_prediction = self.makePrediction( model, self.convertPictureToNumpy( currently_selected_picture)) split = currently_selected_model_name.split('_') if split[4] in ('neg', 'bc', 'bm', 'mc', 'mm'): self.show_binary_prediction( new_prediction, split[4]) else: self.show_five_prediction(new_prediction) else: self.prediction_text.setText( 'No Model is Chosen for Prediction. Choose one to the left.' ) # If the selected picture is not size 299 it will be padded and cropped else: cropped_images = resize_image_padding( currently_selected_picture) self.listview_picture.setRootIndex( self.fileModel_picture.setRootPath('pictures/cropped/%s' % cropped_images)) def on_model_listview_clicked(self, index): global currently_selected_model global currently_selected_picture currently_selected_model = [] selected_model_path = self.dirModel_model.fileInfo( index).absoluteFilePath() currently_selected_model.append(self.getModel(selected_model_path)) self.model_label.setText(currently_selected_model_name[0]) if currently_selected_picture != 'Currently No Image Selected': for model in currently_selected_model: new_prediction = self.makePrediction( model, self.convertPictureToNumpy(currently_selected_picture)) self.show_five_prediction(new_prediction) def on_model_binary_listview_clicked(self): global currently_selected_model global currently_selected_picture currently_selected_model = [] self.prediction_text.setText('') self.model_label.setText('') for x in self.listview_model_binary.selectedIndexes(): selected_model_path = self.dirModel_model_binary.fileInfo( x).absoluteFilePath() currently_selected_model.append( self.getModel(selected_model_path)) # if not currently_selected_model_name: # self.model_label.setText(currently_selected_model_name) if currently_selected_picture != 'Currently No Image Selected': for y in currently_selected_model: new_prediction = self.makePrediction( y, self.convertPictureToNumpy(currently_selected_picture)) self.show_binary_prediction(new_prediction, y.category) def getModel(self, model_path): global currently_selected_model_name currently_selected_model_name = [] split = os.path.split(model_path)[1].split('_') model_version = split[0] + '_' + split[1] + '_' + split[ 2] + '_' + split[3] currently_selected_model_name.append(os.path.split(model_path)[1]) model = getattr(sys.modules[__name__], model_version)() checkpoint_path = model_path + '/cp.ckpt' model.load_weights(checkpoint_path) return model def makePrediction(self, input_model, input_picture): image = tf.reshape(input_picture, [-1, 299, 299, 1]) image = tf.cast(image, tf.float32) image = image / 255.0 return input_model.predict(image) def convertPictureToNumpy(self, filename): img = Image.open(filename) np_array = np.array(img, dtype='uint8') return np_array def show_five_prediction(self, prediction): self.prediction_text.setText( "Probability of Negative: %s" % prediction[0, 0] + "\n\nProbability of Benign Calcification: %s" % prediction[0, 1] + "\n\nProbability of Benign Mass: %s" % prediction[0, 2] + "\n\nProbability of Malignant Calcification: %s" % prediction[0, 3] + "\n\nProbability of Malignant Mass: %s" % prediction[0, 4]) def show_binary_prediction(self, prediction, category): if category == 'neg': self.prediction_text.append( "Probability of Negative: %s %s \n" % (prediction[0, 0], prediction[0, 1])) elif category == 'bc': self.prediction_text.append( "Probability of Benign Calcification: %s %s \n" % (prediction[0, 0], prediction[0, 1])) elif category == 'bm': self.prediction_text.append( "Probability of Benign Mass: %s %s \n" % (prediction[0, 0], prediction[0, 1])) elif category == 'mc': self.prediction_text.append( "Probability of Malignant Calcification: %s %s \n" % (prediction[0, 0], prediction[0, 1])) elif category == 'mm': self.prediction_text.append( "Probability of Malignant Mass: %s %s \n" % (prediction[0, 0], prediction[0, 1])) else: self.prediction_text.append( "Probability of ????: %s %s \n" % (prediction[0, 0], prediction[0, 1])) def openFileDialog(self): fileName, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", "", "All Files (*);;Python Files (*.py)") if fileName: return fileName def is_png(data): return data[:8] == '\x89PNG\x0d\x0a\x1a\x0a'
class TextRenamer(QtWidgets.QMainWindow): ui = None currentFullNames = None currentExtensions = None path = None currentIndex = None showExtension = False def __init__(self): # init user interface: super(TextRenamer, self).__init__() self.show() self.ui = uic.loadUi('textRenamer.ui', self) # TODO: remember last used path self.path = QDir.rootPath() # Set up files and folder views self.foldersModel = QFileSystemModel() self.foldersModel.setRootPath(self.path) self.foldersModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.filesModel = QFileSystemModel() self.filesModel.setFilter(QDir.NoDotAndDotDot | QDir.Files) self.ui.folderView.setModel(self.foldersModel) self.ui.filesView.setModel(self.filesModel) # Remove all columns but the folder name self.ui.folderView.setRootIndex(self.foldersModel.index(self.path)) self.ui.folderView.hideColumn(1) self.ui.folderView.hideColumn(2) self.ui.folderView.hideColumn(3) # Set path for start self.ui.filesView.setRootIndex(self.filesModel.index(self.path)) # Event handlers: self.ui.renameButton.clicked.connect(self.renameFiles) self.ui.folderView.clicked.connect(self.openFolder) self.filesModel.directoryLoaded.connect(self.loadedFolder) self.ui.extensionCheckbox.stateChanged.connect( self.extensionCheckboxChanged) def extensionCheckboxChanged(self, state): if state == 0: self.showExtension = False else: self.showExtension = True self.readCurrentNames() def loadedFolder(self, path): # Delay reading to get correct file order QTimer.singleShot(1, self.readCurrentNames) def readCurrentNames(self): # Reset self.currentFullNames = [] for i in range(self.filesModel.rowCount(self.currentIndex)): self.currentFullNames.append(self.currentIndex.child(i, 0).data()) self.currentNames = [ os.path.splitext(x)[0] for x in self.currentFullNames ] self.currentExtensions = [ os.path.splitext(x)[1] for x in self.currentFullNames ] if self.showExtension: fileListText = '\n'.join(self.currentFullNames) else: fileListText = '\n'.join(self.currentNames) self.ui.newText.setPlainText(fileListText) # Only enable the rename button once everything is loaded self.ui.renameButton.setEnabled(True) def openFolder(self, index): self.path = self.foldersModel.fileInfo(index).absoluteFilePath() self.currentIndex = self.filesModel.setRootPath(self.path) self.ui.filesView.setRootIndex(self.currentIndex) # Clear info text self.ui.errorLabel.setText("") def renameFiles(self): # Read new names (only use as many rows as we have currentFullNames): newNames = self.ui.newText.toPlainText().split( '\n')[:len(self.currentFullNames)] if self.showExtension: self.newFullNames = newNames else: # Add extension self.newFullNames = [ i + j for i, j in zip(newNames, self.currentExtensions) ] # TODO: Add temporary filenames for cases where a new name conflicts with a name that has not yet been renamed # Sanity checkes: enoughNames = False allNamesHaveCharacters = False allNamesUnique = False # Sanity check: All new names have characters if len(self.newFullNames) >= len(self.currentFullNames): enoughNames = True else: self.ui.errorLabel.setText("Error: Not enough names given") # Sanity chcek: All names have characters allNamesHaveCharacters = True for newName in self.newFullNames: if newName == "": allNamesHaveCharacters = False self.ui.errorLabel.setText("Error: Blank new name") break # Sanity chcek: All names unique if self.allUnique(self.newFullNames): allNamesUnique = True else: self.ui.errorLabel.setText("Error: All names have to be unique") renamedCount = 0 notChangedCount = 0 errorCount = 0 # Rename if enoughNames and allNamesHaveCharacters and allNamesUnique: for currentName, newName in zip(self.currentFullNames, self.newFullNames): print(self.path + "/" + currentName + " > " + newName) # Dont rename needlessly if not currentName == newName: currentFile = os.path.join(self.path, currentName).replace( os.sep, '/') newFileName = os.path.join(self.path, newName).replace(os.sep, '/') # Only rename if the current file exists if os.path.exists(currentFile): renamedOk = QtCore.QFile.rename( currentFile, newFileName) if not renamedOk: errorCount += 1 renamedCount += 1 else: notChangedCoint += 1 else: notChangedCount += 1 labelText = "Renamed: " + str(renamedCount) + " files" if notChangedCount > 0: labelText += ", No change: " + str(notChangedCount) if errorCount > 0: labelText += ", Error: " + str(errorCount) # Set info text self.ui.errorLabel.setText(labelText) # Early exit uniqueness checker, returns true if all items in x are unique def allUnique(self, x): seen = set() return not any(i in seen or seen.add(i) for i in x)
class Ui_MainWindow(object): def setupUi(self, MainWindow): self.filename = "untitled" self.temptab="NewTest.C" self.changesSaved = True self._process = [] self.num=21 self.out12="" MainWindow.setObjectName("MainWindow") MainWindow.closeEvent = self.closeEvent MainWindow.resize(1279, 724) MainWindow.setAcceptDrops(False) MainWindow.setAutoFillBackground(False) MainWindow.setStyleSheet("background-color: #31363b;color: white;padding-left: 0.4ex;spacing: 0.2ex;border: 0.1ex dashed #76797c;") MainWindow.showMaximized() self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.centralwidget) self.horizontalLayout_3.setContentsMargins(1, 1, 4, 0) self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.splitter_2 = QtWidgets.QSplitter(self.centralwidget) self.splitter_2.setOrientation(QtCore.Qt.Horizontal) self.splitter_2.setHandleWidth(10) self.splitter_2.setObjectName("splitter_2") self.splitter_2.setStyleSheet("background-color: #232629;") #Tree View self.treeView = QtWidgets.QTreeView(self.splitter_2) path = QDir.rootPath() self.dirModel = QFileSystemModel() self.dirModel.setRootPath(QDir.rootPath()) self.dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.fileModel = QFileSystemModel() self.fileModel.setFilter(QDir.NoDotAndDotDot | QDir.Files) self.model = QtWidgets.QFileSystemModel() self.model.setRootPath((QtCore.QDir.rootPath())) self.treeView.setModel(self.model) self.treeView.setRootIndex(self.dirModel.index(path)) self.treeView.clicked.connect(self.on_clicked) self.treeView.setGeometry(QtCore.QRect(0, 0, 270, 921)) self.treeView.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;") self.treeView.setObjectName("treeView") self.treeView.hideColumn(1) self.treeView.hideColumn(2) self.treeView.hideColumn(3) #Tree View self.splitter = QtWidgets.QSplitter(self.splitter_2) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.splitter.sizePolicy().hasHeightForWidth()) self.splitter.setSizePolicy(sizePolicy) self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setHandleWidth(10) self.splitter.setObjectName("splitter") self.splitter.setStyleSheet("background-color: #232629;") self.frame = QtWidgets.QFrame(self.splitter) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(2) sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) self.frame.setSizePolicy(sizePolicy) self.frame.setStyleSheet("background-color: #232629;") self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame) self.horizontalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout.setSpacing(0) self.horizontalLayout.setObjectName("horizontalLayout") self.tabWidget_2 = QtWidgets.QTabWidget(self.frame) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tabWidget_2.sizePolicy().hasHeightForWidth()) self.tabWidget_2.setSizePolicy(sizePolicy) self.tabWidget_2.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;") self.tabWidget_2.setObjectName("tabWidget_2") self.tab = QtWidgets.QWidget() self.tab.setObjectName("tab") self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.tab) self.verticalLayout_7.setContentsMargins(0, 0, 0, 0) self.verticalLayout_7.setSpacing(0) self.verticalLayout_7.setObjectName("verticalLayout_7") self.plainTextEdit=LineNumber_dark.QCodeEditor(self.tab) self.highlighter=hightest_dark.Highlighter(self.plainTextEdit.document()) self.plainTextEdit.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;") self.plainTextEdit.setObjectName("plainTextEdit") self.plainTextEdit.textChanged.connect(self.changed) self.verticalLayout_7.addWidget(self.plainTextEdit) self.tabWidget_2.addTab(self.tab, "") self.horizontalLayout.addWidget(self.tabWidget_2) self.frame_3 = QtWidgets.QFrame(self.splitter) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(2) sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth()) self.frame_3.setSizePolicy(sizePolicy) self.frame_3.setStyleSheet("background-color: #232629;") self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised) self.frame_3.setObjectName("frame_3") self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_3) self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_2.setSpacing(0) self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.tabWidget = QtWidgets.QTabWidget(self.frame_3) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth()) self.tabWidget.setSizePolicy(sizePolicy) self.tabWidget.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;") self.tabWidget.setTabShape(QtWidgets.QTabWidget.Rounded) self.tabWidget.setObjectName("tabWidget") self.tab1 = QTermWidget() self.tab1.setScrollBarPosition(self.tab1.ScrollBarRight) self.tab1.setColorScheme("WhiteOnBlack") self.tabWidget.addTab(self.tab1, "Terminal") self.tab_3 = QtWidgets.QWidget() self.tab_3.setObjectName("tab_3") self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.tab_3) self.verticalLayout_7.setContentsMargins(0, 0, 0, 0) self.verticalLayout_7.setSpacing(0) self.verticalLayout_7.setObjectName("verticalLayout_7") self.plainTextEdit23=QtWidgets.QPlainTextEdit(self.tab_3) self.plainTextEdit23.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;") self.plainTextEdit23.setObjectName("plainTextEdit23") self.verticalLayout_7.addWidget(self.plainTextEdit23) self.tabWidget.addTab(self.tab_3, "") self.horizontalLayout_2.addWidget(self.tabWidget) self.horizontalLayout_3.addWidget(self.splitter_2) self.verticalLayout_6 = QtWidgets.QVBoxLayout() self.verticalLayout_6.setObjectName("verticalLayout_6") self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setSpacing(0) self.verticalLayout.setObjectName("verticalLayout") self.label_3 = QtWidgets.QLabel(self.centralwidget) font = QtGui.QFont() font.setPointSize(12) self.label_3.setFont(font) self.label_3.setLayoutDirection(QtCore.Qt.LeftToRight) self.label_3.setStyleSheet("background-color: #008000;\n" "color: rgb(255, 255, 255);\n" "border-top-left-radius: 18px;\n" "border-top-right-radius: 18px;\n" "text-align: center;") self.label_3.setTextFormat(QtCore.Qt.AutoText) self.label_3.setAlignment(QtCore.Qt.AlignCenter) self.label_3.setWordWrap(False) self.label_3.setObjectName("label_3") self.verticalLayout.addWidget(self.label_3) self.plainTextEdit_2 = QtWidgets.QPlainTextEdit(self.centralwidget) self.plainTextEdit_2.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;") self.plainTextEdit_2.setObjectName("plainTextEdit_2") self.verticalLayout.addWidget(self.plainTextEdit_2) self.verticalLayout.setStretch(0, 1) self.verticalLayout.setStretch(1, 8) self.verticalLayout_6.addLayout(self.verticalLayout) self.verticalLayout_2 = QtWidgets.QVBoxLayout() self.verticalLayout_2.setSpacing(0) self.verticalLayout_2.setObjectName("verticalLayout_2") self.label_2 = QtWidgets.QLabel(self.centralwidget) font = QtGui.QFont() font.setPointSize(12) self.label_2.setFont(font) self.label_2.setStyleSheet("background-color: #008000;\n" "color: rgb(255, 255, 255);\n" "border-top-left-radius: 18px;\n" "border-top-right-radius: 18px;\n" "text-align: center;") self.label_2.setAlignment(QtCore.Qt.AlignCenter) self.label_2.setObjectName("label_2") self.verticalLayout_2.addWidget(self.label_2) self.plainTextEdit_3 = QtWidgets.QPlainTextEdit(self.centralwidget) self.plainTextEdit_3.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;") self.plainTextEdit_3.setObjectName("plainTextEdit_3") self.verticalLayout_2.addWidget(self.plainTextEdit_3) self.verticalLayout_2.setStretch(0, 1) self.verticalLayout_2.setStretch(1, 8) self.verticalLayout_6.addLayout(self.verticalLayout_2) self.horizontalLayout_3.addLayout(self.verticalLayout_6) self.horizontalLayout_3.setStretch(0, 5) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 1279, 22)) self.menubar.setStyleSheet("background-color: #31363b; color: #eff0f1;") self.menubar.setObjectName("menubar") self.menuFile = QtWidgets.QMenu(self.menubar) self.menuFile.setStyleSheet("background-color: #31363b; color: #eff0f1;") self.menuFile.setObjectName("menuFile") self.menuEdit = QtWidgets.QMenu(self.menubar) self.menuEdit.setStyleSheet("background-color: #31363b; color: #eff0f1;") self.menuEdit.setObjectName("menuEdit") self.menuSettings = QtWidgets.QMenu(self.menubar) self.menuSettings.setStyleSheet("background-color: #31363b; color: #eff0f1;") self.menuSettings.setObjectName("menuSettings") self.menuTheme_select = QtWidgets.QMenu(self.menuSettings) icon227 = QtGui.QIcon() icon227.addPixmap(QtGui.QPixmap("Choose_theme-512.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.menuTheme_select.setIcon(icon227) self.menuTheme_select.setStyleSheet("background-color: #31363b; color: #eff0f1;") self.menuTheme_select.setObjectName("menuTheme_select") self.menuAbout = QtWidgets.QMenu(self.menubar) self.menuAbout.setStyleSheet("background-color: #31363b; color: #eff0f1;") self.menuAbout.setObjectName("menuAbout") self.menuRun = QtWidgets.QMenu(self.menubar) self.menuRun.setStyleSheet("background-color: #31363b; color: #eff0f1;") self.menuRun.setObjectName("menuRun") self.menuSelect_Core = QtWidgets.QMenu(self.menuRun) icon231=QtGui.QIcon() icon231.addPixmap(QtGui.QPixmap(":/Icons/icons8-microchip-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.menuSelect_Core.setIcon(icon231) self.menuSelect_Core.setStyleSheet("background-color: #31363b; color: #eff0f1;") self.menuSelect_Core.setObjectName("menuSelect_Core") self.menuExtensions = QtWidgets.QMenu(self.menubar) self.menuExtensions.setStyleSheet("background-color: #31363b; color: #eff0f1;") self.menuExtensions.setObjectName("menuExtensions") MainWindow.setMenuBar(self.menubar) self.toolButton = QtWidgets.QToolButton() self.toolButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.toolButton.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;") icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(":/Icons/icons8-microchip-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.toolButton.setIcon(icon) self.toolButton.setIconSize(QtCore.QSize(45, 24)) self.toolButton.setPopupMode(QtWidgets.QToolButton.InstantPopup) self.toolButton.setObjectName("toolButton") self.toolBar = QtWidgets.QToolBar(MainWindow) self.toolBar.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.toolBar.setAcceptDrops(False) self.toolBar.setLayoutDirection(QtCore.Qt.RightToLeft) self.toolBar.setStyleSheet("border: 0.1ex transparent #393838;background: 0.1ex solid #31363b;font-weight: bold;") self.toolBar.setMovable(False) self.toolBar.setAllowedAreas(QtCore.Qt.NoToolBarArea) self.toolBar.setIconSize(QtCore.QSize(45, 24)) self.toolBar.setObjectName("toolBar") MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar) self.statusBar = QtWidgets.QStatusBar(MainWindow) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.statusBar.sizePolicy().hasHeightForWidth()) self.statusBar.setSizePolicy(sizePolicy) self.statusBar.setStyleSheet("background-color: rgb(0,128,0,75%);") self.statusBar.setObjectName("statusBar") MainWindow.setStatusBar(self.statusBar) self.spacer=QtWidgets.QWidget() self.spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.uit = QtWidgets.QAction(MainWindow) icon22 = QtGui.QIcon() icon22.addPixmap(QtGui.QPixmap("uit.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.uit.setIcon(icon22) self.uit.setShortcutVisibleInContextMenu(True) self.uit.setObjectName("actionNew") self.uit.triggered.connect(self.open_uit) self.merl = QtWidgets.QAction(MainWindow) icon23 = QtGui.QIcon() icon23.addPixmap(QtGui.QPixmap("merl.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.merl.setIcon(icon23) self.merl.setShortcutVisibleInContextMenu(True) self.merl.setObjectName("actionNew") self.merl.triggered.connect(self.open_site) self.About = QtWidgets.QAction(MainWindow) icon21 = QtGui.QIcon() icon21.addPixmap(QtGui.QPixmap("About_logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.About.setIcon(icon21) self.About.setShortcutVisibleInContextMenu(True) self.About.setObjectName("actionNew") self.About.triggered.connect(self.about_dark) self.actionNew = QtWidgets.QAction(MainWindow) icon1 = QtGui.QIcon() icon1.addPixmap(QtGui.QPixmap(":/Icons/icons8-add-property-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionNew.setIcon(icon1) self.actionNew.setShortcutVisibleInContextMenu(True) self.actionNew.setObjectName("actionNew") self.actionNew.triggered.connect(self.untitled) self.actionOpen = QtWidgets.QAction(MainWindow) icon2 = QtGui.QIcon() icon2.addPixmap(QtGui.QPixmap(":/Icons/icons8-upload-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionOpen.setIcon(icon2) self.actionOpen.setObjectName("actionOpen") self.actionOpen.triggered.connect(self.open_dialog_box) self.actionsave = QtWidgets.QAction(MainWindow) icon3 = QtGui.QIcon() icon3.addPixmap(QtGui.QPixmap(":/Icons/icons8-save-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionsave.setIcon(icon3) self.actionsave.setShortcutVisibleInContextMenu(True) self.actionsave.setObjectName("actionsave") self.actionsave.triggered.connect(self.save_temp) self.actionsave.setShortcut("Ctrl+s") self.actionundo = QtWidgets.QAction(MainWindow) icon4 = QtGui.QIcon() icon4.addPixmap(QtGui.QPixmap(":/Icons/icons8-undo-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionundo.setIcon(icon4) self.actionundo.setVisible(True) self.actionundo.setShortcut("Ctrl+Z") self.actionundo.triggered.connect(self.plainTextEdit.undo) self.actionundo.setShortcutVisibleInContextMenu(True) self.actionundo.setObjectName("actionundo") self.actionRedo = QtWidgets.QAction(MainWindow) icon5 = QtGui.QIcon() icon5.addPixmap(QtGui.QPixmap(":/Icons/icons8-redo-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionRedo.setIcon(icon5) self.actionRedo.setShortcutVisibleInContextMenu(True) self.actionRedo.setObjectName("actionRedo") self.actionRedo.setShortcut("Ctrl+Shift+Z") self.actionRedo.triggered.connect(self.plainTextEdit.redo) self.actioncut = QtWidgets.QAction(MainWindow) icon6 = QtGui.QIcon() icon6.addPixmap(QtGui.QPixmap(":/Icons/icons8-cut-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actioncut.setIcon(icon6) self.actioncut.setShortcutVisibleInContextMenu(True) self.actioncut.setShortcut("Ctrl+X") self.actioncut.triggered.connect(self.plainTextEdit.cut) self.actioncut.setObjectName("actioncut") self.actioncopy = QtWidgets.QAction(MainWindow) icon7 = QtGui.QIcon() icon7.addPixmap(QtGui.QPixmap(":/Icons/icons8-copy-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actioncopy.setIcon(icon7) self.actioncopy.setShortcutVisibleInContextMenu(True) self.actioncopy.setObjectName("actioncopy") self.actioncopy.setShortcut("Ctrl+C") self.actioncopy.triggered.connect(self.plainTextEdit.copy) self.actionpaste = QtWidgets.QAction(MainWindow) icon8 = QtGui.QIcon() icon8.addPixmap(QtGui.QPixmap(":/Icons/icons8-paste-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionpaste.setIcon(icon8) self.actionpaste.setShortcutVisibleInContextMenu(True) self.actionpaste.setObjectName("actionpaste") self.actionpaste.setShortcut("Ctrl+V") self.actionpaste.triggered.connect(self.plainTextEdit.paste) self.actionFind = QtWidgets.QAction(MainWindow) icon9 = QtGui.QIcon() icon9.addPixmap(QtGui.QPixmap(":/Icons/icons8-search-property-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionFind.setIcon(icon9) self.actionFind.setShortcutVisibleInContextMenu(True) self.actionFind.setObjectName("actionFind") self.actionFind.setShortcut("Ctrl+F") self.actionFind.triggered.connect(find.Find(self.plainTextEdit).show) self.actionDark = QtWidgets.QAction(MainWindow) self.actionDark.setObjectName("actionDark") self.actionMERL = QtWidgets.QAction(MainWindow) icon228 = QtGui.QIcon() icon228.addPixmap(QtGui.QPixmap("merl.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionMERL.setIcon(icon228) self.actionMERL.setObjectName("actionMERL") self.actionMERL.triggered.connect(self.open_site) self.actionhelp = QtWidgets.QAction(MainWindow) self.actionhelp.setObjectName("actionhelp") icon229 = QtGui.QIcon() icon229.addPixmap(QtGui.QPixmap("About_logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionhelp.setIcon(icon229) self.actionhelp.triggered.connect(self.about_dark) self.actionRun = QtWidgets.QAction(MainWindow) icon11 = QtGui.QIcon() icon11.addPixmap(QtGui.QPixmap(":/Icons/icons8-play-property-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionRun.setIcon(icon11) self.actionRun.setObjectName("actionRun") self.actionRun.triggered.connect(self.run_Burq) self.actionRun.setEnabled(False) self.actionSave_As = QtWidgets.QAction(MainWindow) icon13 = QtGui.QIcon() icon13.addPixmap(QtGui.QPixmap(":/Icons/icons8-save-as-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionSave_As.setIcon(icon13) self.actionSave_As.setObjectName("actionSave_As") self.actionsave.triggered.connect(self.saveAs) self.actionsave.setShortcut("Ctrl+Shift+s") self.actionHigh_Contrast = QtWidgets.QAction(MainWindow) self.actionHigh_Contrast.setObjectName("actionHigh_Contrast") self.actionHigh_Contrast.triggered.connect(self.light_theme) self.actionChisel_Core = QtWidgets.QAction(MainWindow) icon14 = QtGui.QIcon() icon14.addPixmap(QtGui.QPixmap(":/Icons/icons8-nail-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionChisel_Core.setIcon(icon14) self.actionChisel_Core.setObjectName("actionChisel_Core") self.actionVerilog = QtWidgets.QAction(MainWindow) self.actionVerilog.setObjectName("actionVerilog") icon230 = QtGui.QIcon() icon230.addPixmap(QtGui.QPixmap("Verilator_logo.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionVerilog.setIcon(icon230) self.actionDebug = QtWidgets.QAction(MainWindow) icon15 = QtGui.QIcon() icon15.addPixmap(QtGui.QPixmap(":/Icons/icons8-bug-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionDebug.setIcon(icon15) self.actionDebug.setObjectName("actionDebug") self.actionDebug.triggered.connect(self.termclose) self.actionCompile = QtWidgets.QAction(MainWindow) icon16 = QtGui.QIcon() icon16.addPixmap(QtGui.QPixmap(":/Icons/icons8-new-property-100.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionCompile.setIcon(icon16) self.actionCompile.setObjectName("actionCompile") self.actionCompile.triggered.connect(self.compile_Code) self.actionB_I = QtWidgets.QAction(MainWindow) self.actionB_I.setObjectName("actionB_I") icon232=QtGui.QIcon() icon232.addPixmap(QtGui.QPixmap("micro.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionB_I.setIcon(icon232) self.actionB_I_C = QtWidgets.QAction(MainWindow) self.actionB_I_C.setObjectName("actionB_I_C") icon233=QtGui.QIcon() icon233.addPixmap(QtGui.QPixmap("micro1.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionB_I_C.setIcon(icon233) self.actionB_I_M = QtWidgets.QAction(MainWindow) self.actionB_I_M.setObjectName("actionB_I_M") icon234=QtGui.QIcon() icon234.addPixmap(QtGui.QPixmap("micro2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionB_I_M.setIcon(icon234) self.menuFile.addAction(self.actionNew) self.menuFile.addAction(self.actionOpen) self.menuFile.addAction(self.actionsave) self.menuFile.addAction(self.actionSave_As) self.menuEdit.addAction(self.actionundo) self.menuEdit.addAction(self.actionRedo) self.menuEdit.addAction(self.actioncut) self.menuEdit.addAction(self.actioncopy) self.menuEdit.addAction(self.actionpaste) self.menuEdit.addAction(self.actionFind) self.menuTheme_select.addAction(self.actionDark) self.menuTheme_select.addAction(self.actionHigh_Contrast) self.menuSettings.addAction(self.menuTheme_select.menuAction()) self.menuSettings.addSeparator() self.menuAbout.addAction(self.actionMERL) self.menuAbout.addAction(self.actionhelp) self.menuSelect_Core.addSeparator() self.menuSelect_Core.addSeparator() self.menuSelect_Core.addAction(self.actionChisel_Core) self.menuSelect_Core.addAction(self.actionVerilog) self.menuRun.addAction(self.actionRun) self.menuRun.addAction(self.actionCompile) self.menuRun.addAction(self.menuSelect_Core.menuAction()) self.menuRun.addAction(self.actionDebug) self.menuExtensions.addAction(self.actionB_I) self.menuExtensions.addAction(self.actionB_I_C) self.menuExtensions.addAction(self.actionB_I_M) self.menubar.addAction(self.menuFile.menuAction()) self.menubar.addAction(self.menuEdit.menuAction()) self.menubar.addAction(self.menuSettings.menuAction()) self.menubar.addAction(self.menuAbout.menuAction()) self.menubar.addAction(self.menuExtensions.menuAction()) self.menubar.addAction(self.menuRun.menuAction()) self.toolBar.addAction(self.actionDebug) self.toolBar.addAction(self.actionChisel_Core) self.toolBar.addAction(self.actionVerilog) self.toolBar.addSeparator() self.toolBar.addSeparator() self.toolBar.addAction(self.actionRun) self.toolBar.addAction(self.actionCompile) self.toolBar.addSeparator() self.toolBar.addAction(self.actionFind) self.toolBar.addAction(self.actionsave) self.toolBar.addAction(self.actionNew) self.toolBar.addSeparator() self.toolBar.addWidget(self.toolButton) self.toolButton.addAction(self.actionB_I) self.toolButton.addAction(self.actionB_I_C) self.toolButton.addAction(self.actionB_I_M) self.toolBar.addWidget(self.spacer) self.toolBar.addAction(self.About) self.toolBar.addAction(self.uit) self.toolBar.addAction(self.merl) self.toolBar.addSeparator() self.toolBar.addSeparator() self.actionB_I_C.triggered.connect(self.myfun) self.retranslateUi(MainWindow) self.tabWidget_2.setCurrentIndex(0) self.tabWidget.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(MainWindow) self.count_myfun = 2 self.plainTextEdit_2.isReadOnly() self.plainTextEdit_3.isReadOnly() def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "BURQ IDE")) MainWindow.setWindowIcon(QIcon("About_logo.png")) self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab), _translate("MainWindow", "Untitled")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab1), _translate("MainWindow", "Terminal")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Output")) self.label_3.setText(_translate("MainWindow", "ASSEMBLY CODE")) self.label_2.setText(_translate("MainWindow", "MACHINE CODE")) self.toolButton.setText(_translate("MainWindow", "...")) self.menuFile.setTitle(_translate("MainWindow", "File")) self.menuEdit.setTitle(_translate("MainWindow", "Edit")) self.menuSettings.setTitle(_translate("MainWindow", "Settings")) self.menuTheme_select.setTitle(_translate("MainWindow", "Theme select")) self.menuAbout.setTitle(_translate("MainWindow", "About")) self.menuRun.setTitle(_translate("MainWindow", "Run")) self.menuSelect_Core.setTitle(_translate("MainWindow", "Select Core")) self.menuExtensions.setTitle(_translate("MainWindow", "Extensions")) self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar")) self.actionNew.setText(_translate("MainWindow", "New")) self.actionNew.setShortcut(_translate("MainWindow", "Ctrl+N")) self.actionOpen.setText(_translate("MainWindow", "Import")) self.actionOpen.setShortcut(_translate("MainWindow","Ctrl+O")) self.actionsave.setText(_translate("MainWindow", "Save")) self.actionsave.setShortcut(_translate("MainWindow", "Ctrl+S")) self.actionundo.setText(_translate("MainWindow", "undo")) self.actionundo.setShortcut(_translate("MainWindow", "Ctrl+Z")) self.actionRedo.setText(_translate("MainWindow", "Redo")) self.actionRedo.setShortcut(_translate("MainWindow", "Ctrl+Y")) self.actioncut.setText(_translate("MainWindow", "cut")) self.actioncut.setShortcut(_translate("MainWindow", "Ctrl+X")) self.actioncopy.setText(_translate("MainWindow", "copy")) self.actioncopy.setShortcut(_translate("MainWindow", "Ctrl+V")) self.actionpaste.setText(_translate("MainWindow", "paste")) self.actionpaste.setShortcut(_translate("MainWindow", "Ctrl+V")) self.actionFind.setText(_translate("MainWindow", "Find")) self.actionFind.setShortcut(_translate("MainWindow", "Ctrl+F")) self.actionDark.setText(_translate("MainWindow", "Dracula")) self.actionMERL.setText(_translate("MainWindow", "MERL")) self.actionhelp.setText(_translate("MainWindow", "help")) self.actionRun.setText(_translate("MainWindow", "Run")) self.About.setText(_translate("MainWindow", "About IDE")) self.actionSave_As.setText(_translate("MainWindow", "Save As")) self.actionSave_As.setShortcut(_translate("MainWindow","Crtl+Shift+S")) self.actionHigh_Contrast.setText(_translate("MainWindow", "High Contrast")) self.actionChisel_Core.setText(_translate("MainWindow", "Chisel")) self.actionVerilog.setText(_translate("MainWindow", "Verilog")) self.actionDebug.setText(_translate("MainWindow", "Cancel Process")) self.actionCompile.setText(_translate("MainWindow", "Compile")) self.actionB_I.setText(_translate("MainWindow", "I-Extension")) self.actionB_I_C.setText(_translate("MainWindow", "IC-Extension")) self.actionB_I_M.setText(_translate("MainWindow", "IM-Extension")) self.uit.setText(_translate("MainWindow", "UIT Website")) self.merl.setText(_translate("MainWindow", "MERL Website")) def myfun(self): from subprocess import call if self.count_myfun % 2 == 0: #os.system('python Extraction.py') call(["python3", "Extraction.py"]) file = open("c_converted_machine.txt", "r") assembly = file.read() file.close() self.plainTextEdit_3.setPlainText(assembly) self.count_myfun += 1 else: self.read_MachineCode() self.count_myfun += 1 def on_clicked(self, index): self.num+=1 self.tabWidget_2.setCurrentIndex(self.num) a=setattr(self,"tab",self.num) path = self.fileModel.fileInfo(index).absoluteFilePath() self.treeView.setRootIndex(self.fileModel.setRootPath(path)) print(path) with open(path, "r") as f: print(f.readline()) ff = open(path,"r") c_read = ff.read() #Tab Reading for index values a= QtWidgets.QWidget() a.setObjectName("tab"+str(self.num)) self.verticalLayout_7 = QtWidgets.QVBoxLayout(a) self.verticalLayout_7.setContentsMargins(0, 0, 0, 0) self.verticalLayout_7.setSpacing(0) self.verticalLayout_7.setObjectName("verticalLayout_7") self.tabWidget_2.setTabsClosable(True) self.tabWidget_2.tabCloseRequested.connect(self.removeTab) self.plainTextEdit = LineNumber_dark.QCodeEditor(a) self.highlighter=hightest_dark.Highlighter(self.plainTextEdit.document()) self.plainTextEdit.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;") self.plainTextEdit.setObjectName("plainTextEdit") self.plainTextEdit.textChanged.connect(self.changed) self.verticalLayout_7.addWidget(self.plainTextEdit) self.tabWidget_2.addTab(a, path) self.plainTextEdit.setPlainText(c_read) self.actionFind.triggered.connect(find.Find(self.plainTextEdit).show) def removeTab(self, index): print(index) widget = self.tabWidget_2.widget(index) if widget is not None: widget.deleteLater() def untitled(self,index): self.num+=1 self.tabWidget_2.setCurrentIndex(self.num) a=setattr(self,"tab",self.num) #Tab Reading for index values a= QtWidgets.QWidget() a.setObjectName("tab"+str(self.num)) self.verticalLayout_7 = QtWidgets.QVBoxLayout(a) self.verticalLayout_7.setContentsMargins(0, 0, 0, 0) self.verticalLayout_7.setSpacing(0) self.verticalLayout_7.setObjectName("verticalLayout_7") self.tabWidget_2.setTabsClosable(True) self.tabWidget_2.tabCloseRequested.connect(self.removeTab) self.plainTextEdit = LineNumber_dark.QCodeEditor(a) self.highlighter=hightest_dark.Highlighter(self.plainTextEdit.document()) self.plainTextEdit.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;") self.plainTextEdit.setObjectName("plainTextEdit") self.plainTextEdit.textChanged.connect(self.changed) self.verticalLayout_7.addWidget(self.plainTextEdit) self.tabWidget_2.addTab(a, self.temptab) self.filename=self.temptab self.plainTextEdit.setPlainText("") self.actionFind.triggered.connect(find.Find(self.plainTextEdit).show) def open_dialog_box(self): filename = QFileDialog.getOpenFileName() path = filename[0] print(path) with open(path, "r") as f: print(f.readline()) ff = open(path,"r") c_read = ff.read() #Tab Read initialise self.num+=1 self.tabWidget_2.setCurrentIndex(self.num) a=setattr(self,"tab",self.num) #Tab Read 13 a= QtWidgets.QWidget() a.setObjectName("tab"+str(self.num)) self.verticalLayout_7 = QtWidgets.QVBoxLayout(a) self.verticalLayout_7.setContentsMargins(0, 0, 0, 0) self.verticalLayout_7.setSpacing(0) self.verticalLayout_7.setObjectName("verticalLayout_7") self.tabWidget_2.setTabsClosable(True) self.tabWidget_2.tabCloseRequested.connect(self.removeTab) self.plainTextEdit = LineNumber_dark.QCodeEditor(a) self.highlighter=hightest_dark.Highlighter(self.plainTextEdit.document()) self.plainTextEdit.setStyleSheet("background-color: #232629;;color: #eff0f1;border-radius: 0.2ex;border: 0.1ex solid #76797c;") self.plainTextEdit.setObjectName("plainTextEdit") self.plainTextEdit.textChanged.connect(self.changed) self.verticalLayout_7.addWidget(self.plainTextEdit) self.tabWidget_2.addTab(a, path) self.plainTextEdit.setPlainText(c_read) self.actionFind.triggered.connect(find.Find(self.plainTextEdit).show) def run_Command(self, command = "ls"): program = "tmux" options = [] #options.extend(["send-keys"]) options.extend([command]) options.extend(["\r"]) print(options) for data in range(len(options)): self.tab1.sendText(options[data]) def read_MachineCode(self): file = open("/home/monis/learning-journey3/machinecode.txt", "r") machineCode = file.read() file.close() self.plainTextEdit_3.setPlainText(machineCode) def read_AssemblyCode(self): file = open("/home/monis/learning-journey3/machine.txt", "r") assembly = file.read() file.close() self.plainTextEdit_2.setPlainText(assembly) def save_Code(self): file = open("/home/monis/learning-journey3/test.c", "w") code = self.plainTextEdit.toPlainText() file.write(code) file.close() def compile_Code(self): self.actionRun.setEnabled(False) self.save_Code() self.plainTextEdit_2.setPlainText("") self.plainTextEdit_3.setPlainText("") self.run_Command("cd /home/monis/learning-journey3") self.run_Command("./script2.sh") thread=threading.Thread(target=self.error_check) thread.start() def termclose(self): self.getcode() def output(self): import re time.sleep(0.5) file=open("/home/monis/learning-journey3/output.txt", "r") self.out12=file.read() file.close() self.plainTextEdit23.setPlainText(self.out12) def error_check(self): ##Error Check by GCC Line Number import re time.sleep(0.5) file = open("/home/monis/learning-journey3/meralog.txt", "r") assembly = file.read() x = re.findall(" [0-9] | [1-9999][0-9999] ",assembly) if x==[]: print("No errors") self.actionRun.setEnabled(True) file.close() else: error_line=int(x[-1]) self.plainTextEdit.highlightErrorLine(error_line-1) self.actionRun.setEnabled(False) print(error_line) file.close() def run_Burq(self): self.read_AssemblyCode() self.read_MachineCode() self.run_Command("cd /home/monis/learning-journey3") self.run_Command("./script3.sh") self.output() def getcode(self): self.run_Command("cd /home/monis/learning-journey3") self.run_Command("./script4.sh") self.output() def open_site(self): webbrowser.open('https://www.merledupk.org/') def open_uit(self): webbrowser.open('https://www.uit.edu') def light_theme(self): MainWindow.close() from subprocess import call call(["python3", "LightW.py"]) def about_dark(self): from subprocess import call call(["python3", "about_dark.py"]) def changed(self): self.changesSaved = False def save_temp(self): print(self.changesSaved) print(self.filename) if self.changesSaved ==True: pass elif self.changesSaved ==False: self.saveAs() def saveAs(self): if self.filename =="untitled" or self.filename =="NewTest.C": self.filename = QtWidgets.QFileDialog.getSaveFileName()[0] self.changesSaved = True f=open(self.filename,'w') f.write(self.plainTextEdit.toPlainText()) elif self.filename =="": self.filename = QtWidgets.QFileDialog.getSaveFileName()[0] self.changesSaved = True f=open(self.filename,'w') f.write(self.plainTextEdit.toPlainText()) elif self.filename !="" and self.filename !="untitled" and self.filename !="NewTest.C": f=open(self.filename,'w') f.write(self.plainTextEdit.toPlainText()) def closeEvent(self, event): if self.changesSaved: event.accept() else: popup = QtWidgets.QMessageBox(MainWindow) popup.setIcon(QtWidgets.QMessageBox.Warning) popup.setText("The document has been modified") popup.setInformativeText("Do you want to save your changes?") popup.setStandardButtons(QtWidgets.QMessageBox.Save | QtWidgets.QMessageBox.Cancel | QtWidgets.QMessageBox.Discard) popup.setDefaultButton(QtWidgets.QMessageBox.Save) answer = popup.exec_() if answer == QtWidgets.QMessageBox.Save: self.save_temp() elif answer == QtWidgets.QMessageBox.Discard: event.accept() else: event.ignore()
class App(QWidget): def __init__(self): super().__init__() self.title = 'Whenson\'s Custom INI Merger' self.geo = (200, 200, 800, 600) self.initGUI() def initGUI(self): # windows title and geometry self.setGeometry(*(self.geo)) self.setWindowTitle(self.title) self.show() # master layout and widget definition self.layout = QHBoxLayout() self.file_box = QVBoxLayout() self.list_box = QVBoxLayout() self.btn_group = QVBoxLayout() # deploy layout self.setLayout(self.layout) self.layout.addLayout(self.file_box) self.layout.addLayout(self.list_box) self.layout.addLayout(self.btn_group) # file box self.file_box.addWidget(QLabel('File Browser')) self.folder_tree = QTreeView() self.file_box.addWidget(self.folder_tree) self.file_list = QTreeView() self.file_box.addWidget(self.file_list) # list box self.normal_list = DropListWidget() self.demo_list = DropListWidget() self.list_box.addWidget(QLabel('Output File')) self.list_box.addWidget(QLineEdit()) self.list_box.addWidget(QLabel('Module List')) self.list_box.addWidget(self.normal_list) temp = QHBoxLayout() self.up_btn = QPushButton() self.up_btn.setText('ᐱ') self.down_btn = QPushButton() self.down_btn.setText('ᐯ') self.list_box.addLayout(temp) temp.addWidget(self.up_btn) temp.addWidget(self.down_btn) self.list_box.addWidget(QLabel('With Demostration')) self.list_box.addWidget(self.demo_list) # button group self.merge_btn = QPushButton('Merge') self.btn_group.addWidget(self.merge_btn) self.load_btn = QPushButton('Load') self.btn_group.addWidget(self.load_btn) self.init_file_tree() self.init_drag() def init_file_tree(self): self.dir_model = QFileSystemModel() self.dir_model.setRootPath('C:/') self.dir_model.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot) self.folder_tree.setModel(self.dir_model) self.folder_tree.hideColumn(1) self.folder_tree.hideColumn(2) self.folder_tree.hideColumn(3) self.file_model = QFileSystemModel() self.file_model.setFilter(QDir.NoDotAndDotDot | QDir.Files) self.file_list.setModel(self.file_model) self.file_list.setRootIndex(self.file_model.setRootPath('C:/')) self.file_model.setNameFilters(['*.txt', '*.ini', '*.map']) self.file_model.setNameFilterDisables(False) self.folder_tree.clicked.connect(self.tree_on_clicked) self.file_list.setSelectionMode(QAbstractItemView.ExtendedSelection) def init_drag(self): self.file_list.setDragEnabled(True) self.file_list.setDropIndicatorShown(True) # self.file_list.setDefaultDropAction(Qt.MoveAction) def tree_on_clicked(self, index): path = self.dir_model.fileInfo(index).absoluteFilePath() self.file_list.setRootIndex(self.file_model.setRootPath(path))
class MainWindow(QMainWindow): def __init__(self): super().__init__() self._ui = Ui_MainWindow() self._ui.setupUi(self) self._model = QFileSystemModel() self._model.setRootPath('/') self._setUpViews(self._ui.leftView) self._setUpViews(self._ui.rightView) self._setUpActions() self._setUpButtons() def _setUpViews(self, view): view.setModel(self._model) view.setRootIndex(self._model.index(self._model.rootPath())) view.doubleClicked.connect(self._view_doubleClicked) def _setUpActions(self): self._ui.actionNewFile.triggered.connect(self._newFile_triggered) self._ui.actionNewFolder.triggered.connect(self._newFolder_triggered) self._ui.actionProperties.triggered.connect(self._properties_triggered) self._ui.actionMove.triggered.connect(self._move_triggered) self._ui.actionCopy.triggered.connect(self._copy_triggered) self._ui.actionToTrash.triggered.connect(self._toTrash_triggered) self._ui.actionDelete.triggered.connect(self._delete_triggered) self._ui.actionOpenDefaultApp.triggered.connect( self._defaultApp_triggered) def _setUpButtons(self): self._ui.leftBackButton.clicked.connect(self._leftBack_clicked) self._ui.rightBackButton.clicked.connect(self._rightBack_clicked) self._ui.leftHomeButton.clicked.connect(self._leftHome_clicked) self._ui.rightHomeButton.clicked.connect(self._rightHome_clicked) def _newFile_triggered(self): print('newFile') path = self._getCurrentLocation() newFile, confirmed = QInputDialog.getText(self, 'Create new file', 'File name: ') if confirmed: try: filecommands.newFile(path + '/' + newFile, changeIfExists) except CreateFileError: throwError(f'Can NOT create file {newFile}') def _newFolder_triggered(self): print('newFolder') path = self._getCurrentLocation() newFolder, confirmed = QInputDialog.getText(self, 'Create new folder', 'Folder name: ') if confirmed: try: filecommands.newFolder(path + '/' + newFolder, changeIfExists) except CreateFolderError: throwError(f'Can NOT create folder {newFolder}') def _properties_triggered(self): print('properties') paths = self._getSelectedItemsPath() for path in paths: dialog = PropertiesDialog(path, changeIfExists) dialog.exec_() def _move_triggered(self): print('move') paths = self._getSelectedItemsPath() dst = self._getDestination() for path in paths: try: filecommands.move(path, dst, changeIfExists) except MoveFileError: throwError(f'Can NOT move {path} to {dst}') def _copy_triggered(self): print('copy') paths = self._getSelectedItemsPath() dst = self._getDestination() for path in paths: try: filecommands.copy(path, dst, changeIfExists) except CopyFileError: throwError(f'Can NOT copy {path} to {dst}') def _toTrash_triggered(self): print('toTrash') paths = self._getSelectedItemsPath() for path in paths: try: filecommands.moveToTrash(path) except MoveToTrashError: throwError(f'Can NOT move {path} to trash') def _delete_triggered(self): print('delete') paths = self._getSelectedItemsPath() for path in paths: try: filecommands.delete(path) except DeleteFileError: throwError(f'Can NOT delete {path}') def _defaultApp_triggered(self): print('default') paths = self._getSelectedItemsPath() for path in paths: try: filecommands.openWithDefaultApp(path) except OpenFileError: throwError(f'Can NOT open {path} with default app') def _leftBack_clicked(self): self._goBack(self._ui.leftView) def _rightBack_clicked(self): self._goBack(self._ui.rightView) def _leftHome_clicked(self): self._goHome(self._ui.leftView) def _rightHome_clicked(self): self._goHome(self._ui.rightView) def _view_doubleClicked(self, index): view = self.sender() firstColumnIndex = index.siblingAtColumn(0) fileInfo = self._model.fileInfo(firstColumnIndex) if fileInfo.isDir(): if fileInfo.isReadable(): view.setRootIndex(firstColumnIndex) else: message = QMessageBox( QMessageBox.Critical, 'Permission denied', f'Folder {fileInfo.fileName()} is not readable!') message.exec() elif fileInfo.isFile(): try: filecommands.openWithDefaultApp(fileInfo.absoluteFilePath()) except OpenFileError: message = QMessageBox(QMessageBox.Critical, 'Can NOT open file', f'Can not open {fileInfo.fileName()}') message.exec() def _goBack(self, view): index = view.rootIndex() if index != self._model.index(filecommands.ROOT_PATH): view.setRootIndex(index.parent()) def _goHome(self, view): view.setRootIndex(self._model.index(filecommands.ROOT_PATH)) def _getSelectedItemsPath(self): return { self._model.fileInfo(index).absoluteFilePath() for index in self._ui.leftView.selectedIndexes() } def _getCurrentLocation(self): return self._model.fileInfo( self._ui.leftView.rootIndex()).absoluteFilePath() def _getDestination(self): return self._model.fileInfo( self._ui.rightView.rootIndex()).absoluteFilePath()
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(670, 471) self.centralwidget = QtWidgets.QWidget(MainWindow) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.centralwidget.sizePolicy().hasHeightForWidth()) self.centralwidget.setSizePolicy(sizePolicy) self.centralwidget.setObjectName("centralwidget") self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) self.gridLayout.setObjectName("gridLayout") self.treeView = QtWidgets.QTreeView(self.centralwidget) self.treeView.setObjectName("treeView") self.treeView.setSortingEnabled(True) path = QDir.rootPath() self.dirModel = QFileSystemModel() self.dirModel.setRootPath(QDir.rootPath()) self.fileModel = QFileSystemModel() self.fileModel.setFilter(QDir.NoDotAndDotDot | QDir.Files) self.model = QtWidgets.QFileSystemModel() self.model.setRootPath((QtCore.QDir.rootPath())) self.treeView.setModel(self.model) self.treeView.setRootIndex(self.dirModel.index(path)) self.treeView.doubleClicked.connect(self.on_clicked) self.treeView.setObjectName("treeView") self.treeView.setColumnWidth(0, 300) self.gridLayout.addWidget(self.treeView, 0, 3, 9, 1) self.comboBox = QtWidgets.QComboBox(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.comboBox.sizePolicy().hasHeightForWidth()) self.comboBox.setSizePolicy(sizePolicy) self.comboBox.setObjectName("comboBox") self.comboBox.setEditable(True) self.gridLayout.addWidget(self.comboBox, 1, 0, 1, 3) self.label = QtWidgets.QLabel(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.label.sizePolicy().hasHeightForWidth()) self.label.setSizePolicy(sizePolicy) self.label.setObjectName("label") self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.comboBox_2 = QtWidgets.QComboBox(self.centralwidget) self.comboBox_2.setEnabled(True) self.comboBox_2.setEditable(True) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.comboBox_2.sizePolicy().hasHeightForWidth()) self.comboBox_2.setSizePolicy(sizePolicy) self.comboBox_2.setObjectName("comboBox_2") self.gridLayout.addWidget(self.comboBox_2, 3, 0, 1, 3) self.label_3 = QtWidgets.QLabel(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.label_3.sizePolicy().hasHeightForWidth()) self.label_3.setSizePolicy(sizePolicy) self.label_3.setObjectName("label_3") self.gridLayout.addWidget(self.label_3, 4, 0, 1, 1) self.label_2 = QtWidgets.QLabel(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.label_2.sizePolicy().hasHeightForWidth()) self.label_2.setSizePolicy(sizePolicy) self.label_2.setObjectName("label_2") self.gridLayout.addWidget(self.label_2, 2, 0, 1, 3) logoPath = QDir.homePath() self.logoModel = QFileSystemModel() self.logoModel.setRootPath(logoPath) self.logoModel.setFilter(QDir.NoDotAndDotDot | QDir.Files | QDir.NoSymLinks) print(logoPath) self.comboBox_3 = QtWidgets.QComboBox(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.comboBox_3.sizePolicy().hasHeightForWidth()) self.comboBox_3.setSizePolicy(sizePolicy) self.comboBox_3.setObjectName("comboBox_3") self.comboBox_3.setModel(self.logoModel) self.comboBox_3.setEditable(True) self.gridLayout.addWidget(self.comboBox_3, 5, 0, 1, 3) self.groupBox = QtWidgets.QGroupBox(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.groupBox.sizePolicy().hasHeightForWidth()) self.groupBox.setSizePolicy(sizePolicy) self.groupBox.setObjectName("groupBox") self.checkBox = QtWidgets.QCheckBox(self.groupBox) self.checkBox.setGeometry(QtCore.QRect(10, 20, 70, 17)) self.checkBox.setObjectName("checkBox") self.checkBox_2 = QtWidgets.QCheckBox(self.groupBox) self.checkBox_2.setGeometry(QtCore.QRect(10, 50, 70, 17)) self.checkBox_2.setObjectName("checkBox_2") self.checkBox_3 = QtWidgets.QCheckBox(self.groupBox) self.checkBox_3.setGeometry(QtCore.QRect(10, 80, 70, 17)) self.checkBox_3.setObjectName("checkBox_3") self.checkBox_4 = QtWidgets.QCheckBox(self.groupBox) self.checkBox_4.setGeometry(QtCore.QRect(10, 110, 131, 17)) self.checkBox_4.setObjectName("checkBox_4") self.gridLayout.addWidget(self.groupBox, 7, 0, 1, 2) self.pushButton = QtWidgets.QPushButton(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.pushButton.sizePolicy().hasHeightForWidth()) self.pushButton.setSizePolicy(sizePolicy) self.pushButton.setObjectName("pushButton") self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget) self.pushButton_2.setObjectName("pushButton_2") self.gridLayout.addWidget(self.pushButton, 6, 0, 1, 1) self.gridLayout.addWidget(self.pushButton_2, 6, 1, 1, 1) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 670, 21)) self.menubar.setObjectName("menubar") self.menuFile = QtWidgets.QMenu(self.menubar) self.menuFile.setObjectName("menuFile") self.menuEdit = QtWidgets.QMenu(self.menubar) self.menuEdit.setObjectName("menuEdit") self.menuHelp = QtWidgets.QMenu(self.menubar) self.menuHelp.setObjectName("menuHelp") MainWindow.setMenuBar(self.menubar) self.actionOpen = QtWidgets.QAction(MainWindow) self.actionOpen.setObjectName("actionOpen") self.actionSearch_from_a_specific_Folder = QtWidgets.QAction( MainWindow) self.actionSearch_from_a_specific_Folder.setObjectName( "actionSearch_from_a_specific_Folder") self.actionCut = QtWidgets.QAction(MainWindow) self.actionCut.setObjectName("actionCut") self.actionCopy = QtWidgets.QAction(MainWindow) self.actionCopy.setObjectName("actionCopy") self.actionPaste = QtWidgets.QAction(MainWindow) self.actionPaste.setObjectName("actionPaste") self.actionAbout = QtWidgets.QAction(MainWindow) self.actionAbout.setObjectName("actionAbout") self.menuFile.addAction(self.actionOpen) self.menuFile.addSeparator() self.menuFile.addAction(self.actionSearch_from_a_specific_Folder) self.menuEdit.addAction(self.actionCut) self.menuEdit.addAction(self.actionCopy) self.menuEdit.addAction(self.actionPaste) self.menuEdit.addSeparator() self.menuHelp.addAction(self.actionAbout) self.menuHelp.addSeparator() self.menubar.addAction(self.menuFile.menuAction()) self.menubar.addAction(self.menuEdit.menuAction()) self.menubar.addAction(self.menuHelp.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.label.setText( _translate("MainWindow", "Search for files or folders")) self.label_3.setText(_translate("MainWindow", "TextLabel")) self.label_2.setText(_translate("MainWindow", "Containing Text")) self.groupBox.setTitle(_translate("MainWindow", "Options")) self.checkBox.setText(_translate("MainWindow", "Date")) self.checkBox_2.setText(_translate("MainWindow", "Size")) self.checkBox_3.setText(_translate("MainWindow", "Type")) self.checkBox_4.setText(_translate("MainWindow", "Advance Options")) self.menuFile.setTitle(_translate("MainWindow", "File")) self.menuEdit.setTitle(_translate("MainWindow", "Edit")) self.menuHelp.setTitle(_translate("MainWindow", "Help")) self.actionOpen.setText(_translate("MainWindow", "Open")) self.actionSearch_from_a_specific_Folder.setText( _translate("MainWindow", "Search from a specific Folder")) self.actionCut.setText(_translate("MainWindow", "Cut")) self.actionCopy.setText(_translate("MainWindow", "Copy (Ctrl +C)")) self.actionPaste.setText(_translate("MainWindow", "Paste (Ctrl + P)")) self.actionAbout.setText(_translate("MainWindow", "About")) self.pushButton.setText(_translate("MainWindow", "Search")) self.pushButton.clicked.connect(self.search) self.pushButton_2.setText(_translate("MainWindow", "Stop")) self.pushButton_2.clicked.connect(self.stop) def on_clicked(self, index): path = self.fileModel.fileInfo(index).absoluteFilePath() #Tab Reading for index values os.startfile(path) def stop(self): print("Program Stoped") self.pushButton.setEnabled(True) def search(self): print("Search started") self.pushButton.setEnabled(False) file_name = self.comboBox.currentText() print(file_name) path_tmp1 = self.comboBox_3.currentText() print(path_tmp1) path_tmp = re.findall("[A-Z]:", path_tmp1) print(path_tmp[-1]) cur_dir = path_tmp[-1] + '/' '' print(cur_dir) result = [] # Wlaking top-down from the root if file_name == "": pass else: for root, dir, files in os.walk(cur_dir): for i in files: b = re.findall(".*" + file_name + ".*.*", i, re.IGNORECASE) if b == []: pass elif b != []: for i in files: if b[-1] == i: result.append(os.path.join(root, b[-1])) if result != []: for i in result: print(i) self.pushButton.setEnabled(True) else: print("No match") self.pushButton.setEnabled(True) self.treeView.setFilter(result)
class FileBrowserWidget(QWidget): on_open = pyqtSignal(str) def __init__(self): super().__init__() self.initUI() def initUI(self): self.model = QFileSystemModel() self.rootFolder = '' self.model.setRootPath(self.rootFolder) self.tree = QTreeView() self.tree.setModel(self.model) self.tree.setAnimated(False) self.tree.setIndentation(20) self.tree.setSortingEnabled(True) self.tree.sortByColumn(0, 0) self.tree.setColumnWidth(0, 200) self.tree.setDragEnabled(True) self.tree.setWindowTitle("Dir View") self.tree.resize(640, 480) self.tree.doubleClicked.connect(self.onDblClick) self.tree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.tree.customContextMenuRequested.connect( self.onCustomContextMenuRequested) windowLayout = QVBoxLayout() windowLayout.addWidget(self.tree) windowLayout.setContentsMargins(0, 0, 0, 0) self.setLayout(windowLayout) def onCustomContextMenuRequested(self, point): index = self.tree.indexAt(point) selectedFile = None selectedFolder = None ctx = QMenu("Context menu", self) if index.isValid(): file = self.model.fileInfo(index) selectedFile = file.absoluteFilePath() selectedFolder = selectedFile if file.isDir( ) else file.absolutePath() if file.isDir(): ctx.addAction( "Open in file manager", lambda: QDesktopServices.openUrl( QUrl.fromLocalFile(selectedFile))) if not file.isDir(): for wndTyp, meta in WindowTypes.types: text = 'Open with ' + meta.get('displayName', meta['name']) print(wndTyp, meta) ctx.addAction( QAction(text, self, statusTip=text, triggered=lambda dummy, meta=meta: navigate( "WINDOW", "Type=" + meta['name'], "FileName=" + selectedFile))) ctx.addSeparator() ctx.addAction("Set root folder ...", lambda: self.selectRootFolder(preselect=selectedFolder)) ctx.exec(self.tree.viewport().mapToGlobal(point)) def selectRootFolder(self, preselect=None): if preselect == None: preselect = self.rootFolder dir = QFileDialog.getExistingDirectory(self, "Set root folder", preselect) if dir != None: self.setRoot(dir) def setRoot(self, dir): self.rootFolder = dir self.model.setRootPath(dir) self.tree.setRootIndex(self.model.index(dir)) def onDblClick(self, index): if index.isValid(): file = self.model.fileInfo(index) if not file.isDir(): navigate("OPEN", "FileName=" + file.absoluteFilePath()) def saveState(self): if self.tree.currentIndex().isValid(): info = self.model.fileInfo(self.tree.currentIndex()) return {"sel": info.absoluteFilePath(), "root": self.rootFolder} def restoreState(self, state): try: self.setRoot(state["root"]) except: pass try: idx = self.model.index(state["sel"]) if idx.isValid(): self.tree.expand(idx) self.tree.setCurrentIndex(idx) self.tree.scrollTo(idx, QAbstractItemView.PositionAtCenter) except: pass
class AssetBrowser(QMainWindow, Ui_MainWindow, PlaygroundModule): Name = "asset_browser" def __init__(self, module_manager): super(AssetBrowser, self).__init__() self.setupUi(self) self.init_module(module_manager) self.dir_model = QFileSystemModel() self.dir_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.dir_model.setReadOnly(False) self.dir_view.setModel(self.dir_model) self.dir_view.hideColumn(1) self.dir_view.hideColumn(2) self.dir_view.hideColumn(3) self.file_model = QFileSystemModel() self.file_model.setFilter(QDir.NoDotAndDotDot | QDir.Files) self.file_model.setReadOnly(False) self.file_view.setModel(self.file_model) self.dock = self.modules_manager.new_docked(self, self.Name, "Asset browser", Qt.BottomDockWidgetArea) self.modules_manager.main_window.splitDockWidget(self.dock, self.modules_manager["asset_view"].dock, Qt.Horizontal) def on_open_project(self, project): project_dir = project.project_dir path = os.path.join(project_dir) self.dir_model.setRootPath(path) self.file_model.setRootPath(path) self.dir_view.setRootIndex(self.dir_model.index(path)) self.file_view.setRootIndex(self.file_model.index(path)) def dir_clicked(self, idx): path = self.dir_model.fileInfo(idx).absoluteFilePath() self.file_view.setRootIndex(self.file_model.setRootPath(path)) def file_doubleclicked(self, idx): fileinfo = self.file_model.fileInfo(idx) path = fileinfo.absoluteFilePath() ext = fileinfo.suffix() asset_name = path.replace(self.project_manager.project_dir, '').replace('/src/', '').split('.')[0] self.modules_manager.open_asset(path, asset_name, ext) def file_clicked(self, idx): fileinfo = self.file_model.fileInfo(idx) path = fileinfo.absoluteFilePath() ext = fileinfo.suffix() asset_name = path.replace(self.project_manager.project_dir, '').replace('/src/', '').split('.')[0] self.modules_manager.show_asset(path, asset_name, ext)
class MainWindow(QMainWindow): inputReceived = pyqtSignal(str) def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # Left Browser tabs self.ui.tabWidgetBrowser.removeTab(1) self.ui.tabWidgetBrowser.removeTab(1) self.ui.tabWidgetBrowser.setTabsClosable(True) self.ui.tabWidgetBrowser.tabCloseRequested.connect(self.closeBrowserTab) self.ui.tabWidgetBrowser.tabBarDoubleClicked.connect(lambda: self.maximizeTabs(self.ui.tabWidgetBrowser)) # Left tree views self.fileTreeModel = QFileSystemModel(self) self.fileTreeModel.setRootPath(QDir.currentPath() + QDir.separator() + 'test') self.ui.treeViewFile.setModel(self.fileTreeModel) self.ui.treeViewFile.setRootIndex(self.fileTreeModel.index(QDir.currentPath() + QDir.separator() + 'test')) self.ui.treeViewFile.hideColumn(1) self.ui.treeViewFile.hideColumn(2) self.ui.treeViewFile.hideColumn(3) self.ui.treeViewFile.doubleClicked.connect(self.openFileFromTree) self.ui.treeViewFile.setAnimated(True) self.ui.treeViewSyntax.setAnimated(True) self.ui.treeViewToken.setAnimated(True) self.ui.treeViewFile.setHeaderHidden(True) self.ui.treeViewSyntax.setHeaderHidden(True) self.ui.treeViewToken.setHeaderHidden(True) # Editor tabs self.currentEditor = self.ui.codeEditor self.currentEditor.file = None self.currentEditorTab = self.ui.tabEditor self.openedEditors = [self.currentEditor] self.openedEditorTabs = [self.currentEditorTab] self.currentEditor.setFocus() # set focus self.ui.tabWidgetEditor.tabCloseRequested.connect(self.closeEditorTab) self.ui.tabWidgetEditor.tabBarClicked.connect(self.switchEditorTab) self.ui.tabWidgetEditor.tabBarDoubleClicked.connect(lambda: self.maximizeTabs(self.ui.tabWidgetEditor)) # Bottom console font = QFont() font.setFamily("Courier") font.setStyleHint(QFont.Monospace) font.setFixedPitch(True) font.setPointSize(10) self.ui.console.setFont(font) self.ui.console.setReadOnly(True) self.waitInputCond = QWaitCondition() self.oldConsoleText = None # Bottom output tabs self.ui.tabWidgetOutput.hide() self.ui.tabWidgetOutput.tabCloseRequested.connect(self.closeOutputTab) self.ui.tabWidgetOutput.tabBarDoubleClicked.connect(lambda: self.maximizeTabs(self.ui.tabWidgetOutput)) self.ui.tabWidgetOutput.setTabText(0, 'Console') # Previous opened tabs,for maximizing self.preOpenedTabs = None # Initial size of inner splitter self.ui.splitterInner.setSizes([180, 459 * 2 - 180]) # Menu "File" self.ui.actionOpen.triggered.connect(self.openFile) self.ui.actionNew.triggered.connect(self.newFile) self.ui.actionSave.triggered.connect(self.saveFile) self.ui.actionSaveAs.triggered.connect(self.saveFileAs) self.ui.actionQuit.triggered.connect(self.close) # Menu "Edit" self.connectMenuEditSlots() # Menu "View" self.ui.menuView.triggered.connect(self.manageMenuView) self.ui.actionAboutQt.triggered.connect(QApplication.aboutQt) # Menu "Run" self.ui.actionRun.triggered.connect(self.run) self.ui.actionBuild.triggered.connect(self.runCompile) self.ui.actionShowStable.triggered.connect(self.runSemantic) self.ui.actionRunParser.triggered.connect(self.runParser) self.ui.actionRunLexer.triggered.connect(self.runLexer) @pyqtSlot(bool) def runLexer(self, checked): """ Run lexer and present result on self.ui.tabToken Tree :return: """ p = self.genParser(Parser.mode_lexer) tokenNode = p.lexse() if p else None if not tokenNode: self.endEcho(False) return self.showBrowserTree(self.ui.tabToken, tokenNode) self.endEcho(True) @pyqtSlot(bool) def runParser(self, checked): """ Run parser and present result on self.ui.tabSyntax Tree :return: """ # Begin parse p = self.genParser(Parser.mode_parser) result = p.parse() if p else None if not result: self.endEcho(False) return syntaxNode, tokenNode = result # self.showBrowserTree(self.ui.tabToken, tokenNode) self.ui.treeViewToken.setModel(TreeModel(tokenNode)) self.showBrowserTree(self.ui.tabSyntax, syntaxNode) self.endEcho(True) @pyqtSlot(bool) def runSemantic(self, checked): """ run semantics analysing and print symbol table :return: """ p = self.genParser(Parser.mode_stable) result = p.semantic() if p else None if not result: self.endEcho(False) return stable, syntaxNode, tokenNode = result self.ui.treeViewToken.setModel(TreeModel(tokenNode)) self.ui.treeViewSyntax.setModel(TreeModel(syntaxNode)) self.endEcho(True) @pyqtSlot(bool) def runCompile(self, checked): """ Run compiler and print Intermediate code :return: """ p = self.genParser(Parser.mode_compile) result = p.compile() if p else None if not result: self.endEcho(False) return codes, stable, syntaxNode, tokenNode = result self.ui.treeViewToken.setModel(TreeModel(tokenNode)) self.ui.treeViewSyntax.setModel(TreeModel(syntaxNode)) self.endEcho(True) @pyqtSlot(bool) def run(self, checked): """ compile and run the source code compile in main thread and run in a worker thread """ p = self.genParser(Parser.mode_execute) result = p.compile() if p else None if not result: self.endEcho(False) return codes, stable, syntaxNode, tokenNode = result self.ui.treeViewToken.setModel(TreeModel(tokenNode)) self.ui.treeViewSyntax.setModel(TreeModel(syntaxNode)) console = Console(self.ui.console, parent=self, waitCond=self.waitInputCond) console.update.connect(self.updateOutput) self.inputReceived.connect(console.receivedInput) self.ui.console.blockCountChanged.connect(self.waitInput) self.ui.console.textChanged.connect(self.disableBack) interp = Interpreter(codes, stdin=console, stdout=console, stderr=console) thread = ExecuteThread(interp.inter, self) thread.start() def genParser(self, mode=Parser.mode_execute): """ Generate a parser instance :param mode: :return: """ if not self.saveFile(): return self.showOutputPanel() self.ui.actionViewConsole.setChecked(True) self.beginEcho() stdin = open(self.currentEditor.file, 'r') console = Console(self.ui.console, parent=self) console.update.connect(self.updateOutput) return Parser(stdin, stdout=console, stderr=console, mode=mode) def beginEcho(self): self.updateOutput('%s\n' % self.currentEditor.file) def endEcho(self, success=True): msg = 'successfully' if success else 'unsuccessfully' self.updateOutput('Process finished %s\n' % msg) @pyqtSlot(str) def updateOutput(self, content): """ Update bottom text browser when content is writen to it. :param content: :return: """ self.ui.console.moveCursor(QTextCursor.End) self.ui.console.insertPlainText('%s' % content) self.oldConsoleText = self.ui.console.toPlainText() @pyqtSlot(int) def waitInput(self, newBlockCount): """ :param newBlockCount: line count :return: """ if not self.ui.console.isReadOnly(): self.inputReceived.emit(self.ui.console.toPlainText() .replace(self.oldConsoleText, '')) self.waitInputCond.wakeAll() self.ui.console.setReadOnly(True) @pyqtSlot() def disableBack(self): """ disable backspace when waiting for input :return: """ if not self.ui.console.isReadOnly(): if len(self.oldConsoleText) > len(self.ui.console.toPlainText()): self.ui.console.setPlainText(self.oldConsoleText) self.ui.console.moveCursor(QTextCursor.End) def closeEvent(self, event): """ Override. When Close Event Triggered. Ask user for saving modified files :param event: :return: """ for i in range(len(self.openedEditors)): editor = self.openedEditors[i] editorTab = self.openedEditorTabs[i] if editor.document().isModified(): name = ntpath.basename(editor.file) if editor.file else 'New File' ret = QMessageBox.warning( self, name, 'The document has been modified.\nDo you want to save your changes?', QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) if ret == QMessageBox.Save: event.accept() if self.saveFile() else event.ignore() elif ret == QMessageBox.Discard: index = self.ui.tabWidgetEditor.indexOf(editorTab) self.ui.tabWidgetEditor.removeTab(index) event.accept() else: event.ignore() def showOutputPanel(self): """ Clear previous output and show the ouput panel :return: """ self.ui.console.clear() self.ui.tabWidgetOutput.show() def showBrowserTree(self, tab, rootNode): """ Show treeView on tabWidgetBrowser :param tab: :param rootNode: """ model = TreeModel(rootNode) if tab == self.ui.tabSyntax: treeView = self.ui.treeViewSyntax name = 'Syntax' self.ui.actionViewSystaxTree.setChecked(True) else: treeView = self.ui.treeViewToken name = 'Token' self.ui.actionViewTokenTree.setChecked(True) treeView.setModel(model) # show the tab index = self.ui.tabWidgetBrowser.indexOf(tab) if index == -1: self.ui.tabWidgetBrowser.addTab(tab, name) index = self.ui.tabWidgetBrowser.indexOf(tab) self.ui.tabWidgetBrowser.setCurrentIndex(index) self.addjustBrowserWidth() def connectMenuEditSlots(self): """ set menu "Edit" signals connect to current editor slots :return: """ self.ui.actionCopy.triggered.connect(self.currentEditor.copy) self.ui.actionCut.triggered.connect(self.currentEditor.cut) self.ui.actionPaste.triggered.connect(self.currentEditor.paste) self.ui.actionUndo.triggered.connect(self.currentEditor.undo) self.ui.actionRedo.triggered.connect(self.currentEditor.redo) self.ui.actionSelectAll.triggered.connect(self.currentEditor.selectAll) def disconnectMenuEditSlots(self): """ disconnect menu "Edit" signals :return: """ self.ui.actionCopy.triggered.disconnect(self.currentEditor.copy) self.ui.actionCut.triggered.disconnect(self.currentEditor.cut) self.ui.actionPaste.triggered.disconnect(self.currentEditor.paste) self.ui.actionUndo.triggered.disconnect(self.currentEditor.undo) self.ui.actionRedo.triggered.disconnect(self.currentEditor.redo) self.ui.actionSelectAll.triggered.disconnect(self.currentEditor.selectAll) def createEditorTab(self): """ Create a new Editor tab and set as current editor Should reconnect the signal on menu 'Edit' actions :return: """ # add a new editor self.currentEditorTab = QtWidgets.QWidget() horizontalLayout = QtWidgets.QHBoxLayout(self.currentEditorTab) horizontalLayout.setContentsMargins(0, 0, 0, 0) horizontalLayout.setSpacing(6) codeEditor = CodeEditor(self.currentEditorTab) horizontalLayout.addWidget(codeEditor) self.ui.tabWidgetEditor.addTab(self.currentEditorTab, "") # disconnect signals self.disconnectMenuEditSlots() # change current tab and editors self.currentEditor = codeEditor self.currentEditor.file = None self.openedEditors.append(self.currentEditor) self.openedEditorTabs.append(self.currentEditorTab) # connect signals self.connectMenuEditSlots() # set tab closeable if len(self.openedEditorTabs) > 1: self.ui.tabWidgetEditor.setTabsClosable(True) @pyqtSlot(int) def switchEditorTab(self, index): """ Switch current active editor tab to index Should reconnect the signal on menu 'Edit' actions :param index: :return: """ self.disconnectMenuEditSlots() self.currentEditorTab = self.openedEditorTabs[index] self.currentEditor = self.openedEditors[index] self.connectMenuEditSlots() @pyqtSlot(int) def closeEditorTab(self, index): """ Triggered when closing the editor tab at index requested :param index: :return: """ self.ui.tabWidgetEditor.removeTab(index) self.openedEditorTabs.pop(index) self.openedEditors.pop(index) self.switchEditorTab(0) # choose the beginning tab as current active if len(self.openedEditorTabs) == 1: self.ui.tabWidgetEditor.setTabsClosable(False) @pyqtSlot(int) def closeBrowserTab(self, index): """ Close Left Browser Tab at index :param index: :return: """ # make menu "View" corresponding w = self.ui.tabWidgetBrowser.widget(index) if w == self.ui.tabFile: self.ui.actionViewFiles.setChecked(False) elif w == self.ui.tabToken: self.ui.actionViewTokenTree.setChecked(False) else: self.ui.actionViewSystaxTree.setChecked(False) # remove tab self.ui.tabWidgetBrowser.removeTab(index) if self.ui.tabWidgetBrowser.count() == 0: self.ui.tabWidgetBrowser.hide() @pyqtSlot(int) def closeOutputTab(self, index): """ Close(hide) the output tab widget :param index: """ # make menu "View" corresponding self.ui.actionViewConsole.setChecked(False) self.ui.tabWidgetOutput.hide() def recoverTabWidgets(self): """ recover tabs when cancel maximizing :return: """ for tab in self.preOpenedTabs: tab.show() self.preOpenedTabs = None def storeOpenedTabs(self): """ store tabs opened before maximize :return: """ self.preOpenedTabs = [] if not self.ui.tabWidgetOutput.isHidden(): self.preOpenedTabs.append(self.ui.tabWidgetOutput) if not self.ui.tabWidgetEditor.isHidden(): self.preOpenedTabs.append(self.ui.tabWidgetEditor) if not self.ui.tabWidgetBrowser.isHidden(): self.preOpenedTabs.append(self.ui.tabWidgetBrowser) def maximizeTabs(self, widget): if self.preOpenedTabs: self.recoverTabWidgets() else: self.storeOpenedTabs() for w in [self.ui.tabWidgetBrowser, self.ui.tabWidgetOutput, self.ui.tabWidgetEditor]: if w != widget: w.hide() @pyqtSlot(QAction) def manageMenuView(self, action): """ Handle the action on menu "View" :param action: :return: """ if action == self.ui.actionViewToolbar: self.ui.toolBar.show() if action.isChecked() else self.ui.toolBar.hide() return pair = { self.ui.actionViewFiles: (self.ui.tabWidgetBrowser, self.ui.tabFile, 'File'), self.ui.actionViewTokenTree: (self.ui.tabWidgetBrowser, self.ui.tabToken, 'Token'), self.ui.actionViewSystaxTree: (self.ui.tabWidgetBrowser, self.ui.tabSyntax, 'Syntax'), self.ui.actionViewConsole: (self.ui.tabWidgetOutput, self.ui.tabConsole, 'Console'), } p = pair[action] widget = p[0] tab = p[1] name = p[2] if action.isChecked(): widget.addTab(tab, name) widget.setCurrentWidget(tab) if widget == self.ui.tabWidgetBrowser: # reset tab inner splitter size self.addjustBrowserWidth() if widget.isHidden(): widget.show() else: widget.removeTab( widget.indexOf(tab)) if widget.count() == 0: widget.hide() def addjustBrowserWidth(self): w = self.ui.tabWidgetBrowser.count() * 80 self.ui.splitterInner.setSizes([w, self.ui.splitterInner.width() - w]) @pyqtSlot(bool) def openFile(self, checked=True, path=None): """ Open a new file. If current editor is associated with a file or its content is not null, Then create a new editor tab :return: """ path = QFileDialog.getOpenFileName()[0] if not path else path if len(path) != 0: qfile = QFile(path) if not qfile.open(QFile.ReadOnly or QFile.Text): QMessageBox.warning(self, 'Application', 'Cannot read file %s:\n%s.' % (path, qfile.errorString())) return with open(path, 'r') as _file: content = _file.read() if self.currentEditor.file or len(self.currentEditor.document().toPlainText()) > 0: self.createEditorTab() # associate file on disk with editor self.currentEditor.file = path # update tab name index = self.ui.tabWidgetEditor.indexOf(self.currentEditorTab) _translate = QCoreApplication.translate self.ui.tabWidgetEditor.setTabText( index, _translate("MainWindow", ntpath.basename(path))) self.ui.tabWidgetEditor.setCurrentIndex(index) self.currentEditor.setPlainText(content) @pyqtSlot(int) def openFileFromTree(self, index): f = self.fileTreeModel.fileInfo(index) if f.isFile(): self.openFile(path=f.filePath()) @pyqtSlot(bool) def newFile(self, checked): """ create a new editor tab :param action: :return: """ self.createEditorTab() index = self.ui.tabWidgetEditor.indexOf(self.currentEditorTab) _translate = QCoreApplication.translate self.ui.tabWidgetEditor.setTabText( index, _translate("MainWindow", 'New File')) self.ui.tabWidgetEditor.setCurrentIndex(index) @pyqtSlot(bool) def saveFile(self, checked=None): """ Save file. If current editor is associated with a file on the disk, then save it. Or save file as... :param checked: :return: Saved or canceled """ if self.currentEditor.file: if self.currentEditor.document().isModified(): with open(self.currentEditor.file, 'w') as f: f.write(self.currentEditor.document().toPlainText()) self.currentEditor.document().setModified(False) return True else: return self.saveFileAs() @pyqtSlot(bool) def saveFileAs(self, checked=None): """ Save File As... :param checked: :return: If saved or canceled """ dialog = QFileDialog() dialog.setWindowModality(Qt.WindowModal) dialog.setAcceptMode(QFileDialog.AcceptSave) if dialog.exec_(): filepath = dialog.selectedFiles()[0] with open(filepath, 'w') as f: f.write(self.currentEditor.document().toPlainText()) self.currentEditor.document().setModified(False) self.currentEditor.file = filepath return True else: return False
class Explorer(QWidget): def __init__(self, rootdir=QDir.rootPath()): QWidget.__init__(self) self.treeview = QTreeView() self.listview = QListView() self.path = rootdir self.filename = '' self.filepath = rootdir self.canvas = None self.col_selector = None self.header = '' self.xcol = [1] self.ycol = [1] self.ncols = 0 self.dirModel = QFileSystemModel() self.dirModel.setRootPath(self.path) self.dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.fileModel = QFileSystemModel() self.fileModel.setRootPath(self.filepath) self.fileModel.setFilter(QDir.NoDotAndDotDot | QDir.Files) self.fileModel.setNameFilters(['*.txt']) self.fileModel.setNameFilterDisables(0) self.treeview.setModel(self.dirModel) self.listview.setModel(self.fileModel) for i in [1, 2, 3]: self.treeview.setColumnHidden(i, True) self.treeview.setHeaderHidden(True) self.treeview.setRootIndex(self.dirModel.index(self.path)) self.listview.setRootIndex(self.fileModel.index(self.path)) self.treeview.clicked.connect(self.on_clicked) self.listview.selectionModel().currentChanged.connect(self.file_selected) self.listview.selectionModel().currentChanged.connect(lambda: self.canvas.update_plot(self)) self.listview.selectionModel().currentChanged.connect(lambda: self.col_selector.update_range(self.ncols)) def on_clicked(self, index): self.path = self.dirModel.fileInfo(index).absoluteFilePath() self.listview.setRootIndex(self.fileModel.setRootPath(self.path)) def file_selected(self, index): self.filename = self.fileModel.fileName(index) self.filepath = self.fileModel.filePath(index) self.load_file() def load_file(self): try: if self.filepath.endswith('.txt'): with open(self.filepath, 'r') as file: self.header, self.xcol, self.ycol = '', [], [] for ln in file: if ln.startswith('#'): self.header += ln[2:] else: cols = ln.split('\t') self.xcol.append(float(cols[0])) self.ycol.append(float(cols[self.col_selector.sp.value()])) self.ncols = len(cols) self.col_selector.update_range(self.ncols) except: self.header, self.xcol, self.ycol = '', [0], [0] def update_rootdir(self, rootdir): self.path = rootdir self.treeview.setRootIndex(self.dirModel.index(self.path)) self.listview.setRootIndex(self.fileModel.index(self.path))
class Chapterize(QMainWindow): def __init__(self): super().__init__() self.ui = Ui_ChapterizeWindow() self.ui.setupUi(self) self.dir = QDir.homePath() self.chaptersTableModel = ChaptersTableModel() self.ui.chapterTable.setModel(self.chaptersTableModel) self.ui.chapterTable.setItemDelegate(TimestampDelegate()) self.ui.chapterTable.contextMenuEvent = self.onChapterContextMenu self.mp3ListModel = QFileSystemModel() self.mp3ListModel.setNameFilters(['*.mp3']) self.mp3ListModel.setFilter(QDir.Files) self.mp3ListModel.setRootPath(self.dir) self.mp3ListModel.setNameFilterDisables(False) self.ui.mp3List.setModel(self.mp3ListModel) self.ui.mp3List.setRootIndex(self.mp3ListModel.index(self.dir)) self.ui.mp3List.selectionModel().selectionChanged.connect(self.onMp3Select) self.ui.actionChangeDir.triggered.connect(self.onDirectoryChange) self.ui.actionExit.triggered.connect(self.close) self.ui.actionSave.triggered.connect(self.chaptersTableModel.save) @pyqtSlot() def onDirectoryChange(self): chosen_dir = QFileDialog.getExistingDirectory(self, "Change Directory...", self.dir, QFileDialog.ShowDirsOnly) if chosen_dir != '': self.dir = chosen_dir self.mp3ListModel.setRootPath(self.dir) self.ui.mp3List.setRootIndex(self.mp3ListModel.index(self.dir)) @pyqtSlot(QItemSelection, QItemSelection) def onMp3Select(self, selected, deselected): sel_idx = selected.indexes()[0] pth = self.mp3ListModel.fileInfo(sel_idx).absoluteFilePath() self.chaptersTableModel.set_file(pth) @pyqtSlot(QContextMenuEvent) def onChapterContextMenu(self, e): idx = self.ui.chapterTable.indexAt(e.pos()) row = idx.row() if row < 0: row = self.chaptersTableModel.rowCount() menu = QMenu(self) insertAction = QAction('&Insert', menu) insertAction.triggered.connect(lambda: self.chaptersTableModel.insertRow(row)) menu.addAction(insertAction) deleteAction = QAction('&Delete', menu) deleteAction.triggered.connect(lambda: self.chaptersTableModel.removeRow(row)) menu.addAction(deleteAction) menu.exec_(e.globalPos())
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(874, 596) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.verticalLayout = QtWidgets.QVBoxLayout(MainWindow) self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.horizontalLayout.addWidget(self.centralwidget) self.frame = QtWidgets.QFrame(self.centralwidget) self.frame.setGeometry(QtCore.QRect(0, 0, 871, 41)) self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Sunken) self.frame.setObjectName("frame") self.line = QtWidgets.QFrame(self.frame) self.line.setGeometry(QtCore.QRect(43, 0, 20, 41)) self.line.setFrameShape(QtWidgets.QFrame.VLine) self.line.setFrameShadow(QtWidgets.QFrame.Sunken) self.line.setObjectName("line") self.line_2 = QtWidgets.QFrame(self.frame) self.line_2.setGeometry(QtCore.QRect(180, 0, 20, 41)) self.line_2.setFrameShape(QtWidgets.QFrame.VLine) self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken) self.line_2.setObjectName("line_2") self.widget = QtWidgets.QWidget(self.centralwidget) self.widget.setGeometry(QtCore.QRect(0, 40, 221, 541)) self.widget.setObjectName("widget") self.label = QtWidgets.QLabel(self.widget) self.label.setGeometry(QtCore.QRect(10, 10, 191, 16)) self.label.setObjectName("label") self.label_2 = QtWidgets.QLabel(self.widget) self.label_2.setGeometry(QtCore.QRect(10, 70, 201, 16)) self.label_2.setObjectName("label_2") self.label_3 = QtWidgets.QLabel(self.widget) self.label_3.setGeometry(QtCore.QRect(10, 140, 191, 16)) self.label_3.setObjectName("label_3") self.groupBox = QtWidgets.QGroupBox(self.widget) self.groupBox.setGeometry(QtCore.QRect(10, 250, 201, 141)) self.groupBox.setObjectName("groupBox") self.checkBox = QtWidgets.QCheckBox(self.groupBox) self.checkBox.setGeometry(QtCore.QRect(10, 20, 70, 17)) self.checkBox.setShortcut("") self.checkBox.setTristate(False) self.checkBox.setObjectName("checkBox") self.checkBox_2 = QtWidgets.QCheckBox(self.groupBox) self.checkBox_2.setGeometry(QtCore.QRect(10, 50, 70, 17)) self.checkBox_2.setObjectName("checkBox_2") self.checkBox_3 = QtWidgets.QCheckBox(self.groupBox) self.checkBox_3.setGeometry(QtCore.QRect(10, 80, 70, 17)) self.checkBox_3.setObjectName("checkBox_3") self.checkBox_4 = QtWidgets.QCheckBox(self.groupBox) self.checkBox_4.setGeometry(QtCore.QRect(10, 110, 111, 17)) self.checkBox_4.setObjectName("checkBox_4") self.pushButton = QtWidgets.QPushButton(self.widget) self.pushButton.setGeometry(QtCore.QRect(10, 200, 75, 23)) self.pushButton.setObjectName("pushButton") self.pushButton_2 = QtWidgets.QPushButton(self.widget) self.pushButton_2.setGeometry(QtCore.QRect(100, 200, 75, 23)) self.pushButton_2.setObjectName("pushButton_2") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 874, 21)) self.menubar.setObjectName("menubar") self.menuFile = QtWidgets.QMenu(self.menubar) self.menuFile.setObjectName("menuFile") self.menuEdit = QtWidgets.QMenu(self.menubar) self.menuEdit.setObjectName("menuEdit") self.menuTools = QtWidgets.QMenu(self.menubar) self.menuTools.setObjectName("menuTools") self.menuHelp = QtWidgets.QMenu(self.menubar) self.menuHelp.setObjectName("menuHelp") MainWindow.setMenuBar(self.menubar) self.actionAbout = QtWidgets.QAction(MainWindow) self.actionAbout.setObjectName("actionAbout") self.actionOpen = QtWidgets.QAction(MainWindow) self.actionOpen.setObjectName("actionOpen") self.actionSearch_From_Specific_Location = QtWidgets.QAction( MainWindow) self.actionSearch_From_Specific_Location.setObjectName( "actionSearch_From_Specific_Location") self.actionDelete = QtWidgets.QAction(MainWindow) self.actionDelete.setObjectName("actionDelete") self.actionExit = QtWidgets.QAction(MainWindow) self.actionExit.setObjectName("actionExit") self.actionCut = QtWidgets.QAction(MainWindow) self.actionCut.setObjectName("actionCut") self.actionCopy = QtWidgets.QAction(MainWindow) self.actionCopy.setObjectName("actionCopy") self.actionClear_List = QtWidgets.QAction(MainWindow) self.actionClear_List.setObjectName("actionClear_List") self.actionSelect_All = QtWidgets.QAction(MainWindow) self.actionSelect_All.setObjectName("actionSelect_All") self.actionProperties = QtWidgets.QAction(MainWindow) self.actionProperties.setObjectName("actionProperties") self.menuFile.addAction(self.actionOpen) self.menuFile.addSeparator() self.menuFile.addAction(self.actionSearch_From_Specific_Location) self.menuFile.addAction(self.actionDelete) self.menuFile.addSeparator() self.menuFile.addAction(self.actionExit) self.menuEdit.addAction(self.actionCut) self.menuEdit.addAction(self.actionCopy) self.menuEdit.addSeparator() self.menuEdit.addAction(self.actionClear_List) self.menuEdit.addAction(self.actionSelect_All) self.menuTools.addAction(self.actionProperties) self.menuTools.addSeparator() self.menuHelp.addAction(self.actionAbout) self.menuHelp.addSeparator() self.menubar.addAction(self.menuFile.menuAction()) self.menubar.addAction(self.menuEdit.menuAction()) self.menubar.addAction(self.menuTools.menuAction()) self.menubar.addAction(self.menuHelp.menuAction()) #Search column View #self.columnView = QtWidgets.QColumnView(self.centralwidget) #self.columnView.setGeometry(QtCore.QRect(220, 50, 651, 521)) #self.columnView.setResizeGripsVisible(True) #self.columnView.setObjectName("columnView") self.treeView = QtWidgets.QTreeView(self.centralwidget) self.treeView.setGeometry(QtCore.QRect(220, 50, 651, 521)) self.treeView.setObjectName("columnView") self.horizontalLayout.addWidget(self.treeView) path = QDir.rootPath() self.dirModel = QFileSystemModel() self.dirModel.setRootPath(QDir.rootPath()) self.fileModel = QFileSystemModel() self.fileModel.setFilter(QDir.NoDotAndDotDot | QDir.Files) self.model = QtWidgets.QFileSystemModel() self.model.setRootPath((QtCore.QDir.rootPath())) self.treeView.setModel(self.model) self.treeView.setRootIndex(self.dirModel.index(path)) self.treeView.doubleClicked.connect(self.on_clicked) self.treeView.setObjectName("treeView") self.treeView.setColumnWidth(0, 300) logoPath = QDir.homePath() self.logoModel = QFileSystemModel() self.logoModel.setRootPath(logoPath) self.logoModel.setFilter(QDir.NoDotAndDotDot | QDir.Files | QDir.NoSymLinks) print(logoPath) self.comboBox = QtWidgets.QComboBox(self.widget) self.comboBox.setGeometry(QtCore.QRect(10, 30, 201, 31)) self.comboBox.setEditable(True) self.comboBox.setObjectName("comboBox") self.comboBox_2 = QtWidgets.QComboBox(self.widget) self.comboBox_2.setGeometry(QtCore.QRect(10, 100, 201, 31)) self.comboBox_2.setEditable(True) self.comboBox_2.setObjectName("comboBox_2") self.comboBox_3 = QtWidgets.QComboBox(self.widget) self.comboBox_3.setGeometry(QtCore.QRect(10, 160, 201, 31)) self.comboBox_3.setEditable(True) self.comboBox_3.setObjectName("comboBox_3") self.comboBox_3.setModel(self.logoModel) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.label.setText( _translate("MainWindow", "Search for files or folders")) self.label_2.setText( _translate("MainWindow", "Containing text (for wordprocessor files)")) self.label_3.setText(_translate("MainWindow", "Look in (Directory)")) self.groupBox.setTitle(_translate("MainWindow", "Options")) self.checkBox.setText(_translate("MainWindow", "Date")) self.checkBox_2.setText(_translate("MainWindow", "Size")) self.checkBox_3.setText(_translate("MainWindow", "Type")) self.checkBox_4.setText(_translate("MainWindow", "Advance Options")) self.pushButton.setText(_translate("MainWindow", "Search")) self.pushButton.clicked.connect(self.search) self.pushButton_2.setText(_translate("MainWindow", "Stop")) self.pushButton_2.clicked.connect(self.stop) self.menuFile.setTitle(_translate("MainWindow", "File")) self.menuEdit.setTitle(_translate("MainWindow", "Edit")) self.menuTools.setTitle(_translate("MainWindow", "Tools")) self.menuHelp.setTitle(_translate("MainWindow", "Help")) self.actionAbout.setText(_translate("MainWindow", "About")) self.actionOpen.setText(_translate("MainWindow", "Open")) self.actionSearch_From_Specific_Location.setText( _translate("MainWindow", "Search From Specific Location")) self.actionDelete.setText(_translate("MainWindow", "Delete")) self.actionExit.setText(_translate("MainWindow", "Exit")) self.actionCut.setText(_translate("MainWindow", "Cut")) self.actionCopy.setText(_translate("MainWindow", "Copy")) self.actionClear_List.setText(_translate("MainWindow", "Clear List")) self.actionSelect_All.setText(_translate("MainWindow", "Select All")) self.actionProperties.setText(_translate("MainWindow", "Properties")) def on_clicked(self, index): path = self.fileModel.fileInfo(index).absoluteFilePath() #Tab Reading for index values os.startfile(path) def stop(self): print("Program Stoped") self.pushButton.setEnabled(True) def search(self): print("Search started") self.pushButton.setEnabled(False) file_name = self.comboBox.currentText() print(file_name) path_tmp1 = self.comboBox_3.currentText() print(path_tmp1) path_tmp = re.findall("[A-Z]:", path_tmp1) print(path_tmp[-1]) cur_dir = path_tmp[-1] + '/' '' print(cur_dir) result = [] # Wlaking top-down from the root for root, dir, files in os.walk(cur_dir): for i in files: b = re.findall(".*" + file_name + ".*.*", i, re.IGNORECASE) if b == []: pass elif b != []: for i in files: if b[-1] == i: result.append(os.path.join(root, b[-1])) if result != []: for i in result: print(i) self.pushButton.setEnabled(True) else: print("No match") self.pushButton.setEnabled(True)
class FileWidget(QWidget): def __init__(self): super().__init__() # QWidget部件是PyQt5所有用户界面对象的基类。他为QWidget提供默认构造函数。默认构造函数没有父类。 # 创建一个文件系统模型 self.file_model = QFileSystemModel() # 设置目录为当前工作目录 self.file_model.setRootPath(QDir.currentPath()) # 创建树视图,构建文件目录视图 self.treeview = QTreeView() # 绑定此文件模型 self.treeview.setModel(self.file_model) ''' 设置当前勾结点索引为当前工作目录 如果想从整个文件系统根节点开始浏览视图, 简单删掉此行即可 ''' self.treeview.setRootIndex(self.file_model.index(QDir.currentPath())) # 头部显示排序戳 self.treeview.header().setSortIndicatorShown(True) # 创建右键菜单 self.treeview.setContextMenuPolicy(Qt.CustomContextMenu) # point = self.treeview.pos() self.treeview.customContextMenuRequested.connect(self.generateMenu) ''' # 底部按钮布局 self.mkdirButton = QPushButton("Make Directory...") self.rmButton = QPushButton("Remove") buttonLayout = QHBoxLayout() buttonLayout.addWidget(self.mkdirButton) buttonLayout.addWidget(self.rmButton) ''' # 文件管理界面布局 layout = QVBoxLayout() layout.addWidget(self.treeview) # layout.addLayout(buttonLayout) # resize()方法调整窗口的大小。600px宽300px高 self.resize(600, 300) # move()方法移动窗口在屏幕上的位置到x = 300,y = 300坐标。 self.move(300, 300) # 设置窗口的标题 self.setWindowTitle('File Manage') # 设置窗口的图标 self.setWindowIcon(QIcon('File-Explorer.png')) self.setLayout(layout) # 生成右键菜单 def generateMenu(self, position): # 索引默认值 row_num = -1 # 遍历确定行号 for i in self.treeview.selectionModel().selection().indexes(): row_num = i.row() # 保证选中有效项 if row_num != -1: # 创建右键菜单 menu = QMenu() # 提供删除和创建文件/文件夹选项 item1 = menu.addAction("Delete") item2 = menu.addAction("NewDirectory") # 在光标处显示执行菜单 action = menu.exec_(self.treeview.mapToGlobal(position)) if action == item1: #弹出消息框确认此次删除操作 res = self.msgbox() if res: self.delete() else: return elif action == item2: self.mkdirectory() else: return else: return # 删除选定文件/文件夹 def delete(self): index = self.treeview.currentIndex() if index.isValid(): fileInfo = self.file_model.fileInfo(index) if fileInfo.isDir(): self.file_model.rmdir(index) else: self.file_model.remove(index) # 确认框 def msgbox(self): msgBox = QMessageBox() msgBox.setWindowTitle("Warning") msgBox.setText("Delete the file/dir you selected?") msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msgBox.setDefaultButton(QMessageBox.No) # button = QMessageBox.question("Warning", "delete the file/dir?", # QMessageBox.Yes | QMessageBox.No, QMessageBox.No) button = msgBox.exec_() if button == QMessageBox.No: return False elif button == QMessageBox.Yes: return True # 创建文件夹 def mkdirectory(self): index = self.treeview.rootIndex() if index.isValid(): # 弹出输入框录入文件名 dirname, ok = QInputDialog.getText(self, "File Name", "Input an unique dir name:") if ok: self.file_model.mkdir(index, dirname) else: return def keyPressEvent(self, event): if event.key() == Qt.Key_F3: self.close()