class FolderView(QWidget): movieFound = pyqtSignal(list) def __init__(self, config): super().__init__() self.config = config['FolderView'] self.resize(200, 400) self.setMaximumWidth(200) self.setMinimumWidth(150) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.currPath = QLineEdit() self.model = QFileSystemModel() self.model.rootPathChanged.connect(self.currPath.setText) self.folderList = FolderList(self.config, parent=self) self.folderList.setModel(self.model) self.folderList.changeDir(self.config.get('currdir', '')) layout.addWidget(self.currPath) layout.addWidget(self.folderList) self.setLayout(layout) def setCurrentIndex(self, index): self.folderList.setCurrentIndex(index) self.folderList.onListClicked(index) def getPath(self, index = None): if not index: index = self.folderList.currentIndex() return self.model.filePath(index) def rootPath(self): return self.model.rootPath() def getSelectedIndexes(self): return self.folderList.selectedIndexes() def getFiles(self, index): return self.folderList.getFiles(index) def playFile(self): index = self.folderList.currentIndex() if not index.isValid(): return import glob exts = ('*.mp4', '*.mkv', '*.avi', '*.wmv') files = [] path = self.model.filePath(index) #print(path) for ext in exts: files.extend(glob.glob('%s/%s'%(path, ext))) if len(files) < 1: return files.sort() os.startfile(files[0])
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.__buildModelView() ## ==============自定义功能函数============ def __buildModelView(self): ##构造Model/View 系统 self.model = QFileSystemModel(self) self.model.setRootPath(QDir.currentPath()) self.ui.treeView.setModel(self.model) #设置数据模型 self.ui.listView.setModel(self.model) self.ui.tableView.setModel(self.model) self.ui.treeView.clicked.connect(self.ui.listView.setRootIndex) self.ui.treeView.clicked.connect(self.ui.tableView.setRootIndex) ## ==========由connectSlotsByName() 自动连接的槽函数================== def on_treeView_clicked(self, index): ##treeView单击 self.ui.chkBox_IsDir.setChecked(self.model.isDir(index)) #是否是目录 self.ui.LabPath.setText(self.model.filePath(index)) #目录名 self.ui.LabType.setText(self.model.type(index)) #节点类型 self.ui.LabFileName.setText(self.model.fileName(index)) #文件名 fileSize = self.model.size(index) / 1024 if (fileSize < 1024): self.ui.LabFileSize.setText("%d KB" % fileSize) else: self.ui.LabFileSize.setText("%.2f MB" % (fileSize / 1024.0))
class FileSystemTreeView(QTreeView, QDockWidget): def __init__(self, parent=None): super().__init__(parent=parent) self.mainwindow = parent self.fileSystemModel = QFileSystemModel() self.fileSystemModel.setRootPath('.') self.setModel(self.fileSystemModel) # 隐藏size,date等列 self.setColumnWidth(0, 200) self.setColumnHidden(1, True) self.setColumnHidden(2, True) self.setColumnHidden(3, True) # 不显示标题栏 self.header().hide() # 设置动画 self.setAnimated(True) # 选中不显示虚线 self.setFocusPolicy(Qt.NoFocus) self.doubleClicked.connect(self.select_image) self.setMinimumWidth(200) def select_image(self, file_index): file_name = self.fileSystemModel.filePath(file_index) if file_name.endswith(('.jpg', '.png', '.bmp')): src_img = imdecode(np.fromfile(file_name, dtype=np.uint8), -1) self.mainwindow.change_image(src_img)
class SessionParamWidget(Qt.QWidget): def __init__(self, parent=None): Qt.QWidget.__init__(self, parent) self.file_model = QFileSystemModel() def set_directory(self,directory): self.directory = directory self.file_model.setRootPath(directory) def setup_tree(self): self.folder_select_tree.setModel(self.file_model) self.folder_select_tree.setRootIndex(self.file_model.index(self.directory)); def connect_tree(self): self.folder_select_tree.clicked.connect(self.set_session_folder) def set_session_folder(self, index): indexItem = self.file_model.index(index.row(), 0, index.parent()) fileName = self.file_model.fileName(indexItem) filePath = self.file_model.filePath(indexItem) print(fileName) print(filePath)
class QmyMainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.model = QFileSystemModel(self) self.model.setRootPath(QDir.currentPath()) self.ui.qTreeView.setModel(self.model) self.ui.qListView.setModel(self.model) self.ui.qTableView.setModel(self.model) self.ui.qTreeView.clicked.connect(self.ui.qListView.setRootIndex) self.ui.qTreeView.clicked.connect(self.ui.qTableView.setRootIndex) def on_qTreeView_clicked(self, index): self.ui.qCheckBox.setChecked(self.model.isDir(index)) self.ui.qLabel1.setText(self.model.filePath(index)) self.ui.qLabel4.setText(self.model.type(index)) self.ui.qLabel2.setText(self.model.fileName(index)) fileSize = self.model.size(index)/1024 if(fileSize<1024): self.ui.qLabel3.setText("%d KB" % fileSize) else: self.ui.qLabel3.setText("%.2f MB" % (fileSize/1024))
class App(QWidget): def __init__(self): super().__init__() self.title = 'PyQt5 file system view - pythonspot.com' 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() r_inx = self.model.setRootPath(".") self.tree = QTreeView() self.tree.setModel(self.model) self.tree.setAnimated(False) self.tree.setIndentation(15) self.tree.setSortingEnabled(True) self.tree.setWindowTitle("Dir View") self.tree.resize(640, 480) windowLayout = QVBoxLayout() windowLayout.addWidget(self.tree) self.setLayout(windowLayout) print(self.model.rootPath()) print(self.model.filePath(self.model.parent(r_inx))) index_temp = self.model.index(0, 0, QModelIndex()) print(self.model.fileName(index_temp)) self.show()
class FileChooser(QWidget): fileOpened = pyqtSignal(str) def __init__(self, parent=None): super().__init__(parent) self.folderBox = QComboBox(self) self.explorerTree = FileTreeView(self) self.explorerTree.doubleClickCallback = self._fileOpened self.explorerModel = QFileSystemModel(self) self.explorerModel.setFilter( QDir.AllDirs | QDir.Files | QDir.NoDotAndDotDot) self.explorerModel.setNameFilters(["*.py"]) self.explorerModel.setNameFilterDisables(False) self.explorerTree.setModel(self.explorerModel) for index in range(1, self.explorerModel.columnCount()): self.explorerTree.hideColumn(index) self.setCurrentFolder() self.folderBox.currentIndexChanged[int].connect( self.updateCurrentFolder) layout = QVBoxLayout(self) layout.addWidget(self.folderBox) layout.addWidget(self.explorerTree) layout.setContentsMargins(5, 5, 0, 0) def _fileOpened(self, modelIndex): path = self.explorerModel.filePath(modelIndex) if os.path.isfile(path): self.fileOpened.emit(path) def currentFolder(self): return self.explorerModel.rootPath() def setCurrentFolder(self, path=None): if path is None: app = QApplication.instance() path = app.getScriptsDirectory() else: assert os.path.isdir(path) self.explorerModel.setRootPath(path) self.explorerTree.setRootIndex(self.explorerModel.index(path)) self.folderBox.blockSignals(True) self.folderBox.clear() style = self.style() dirIcon = style.standardIcon(style.SP_DirIcon) self.folderBox.addItem(dirIcon, os.path.basename(path)) self.folderBox.insertSeparator(1) self.folderBox.addItem(self.tr("Browse…")) self.folderBox.setCurrentIndex(0) self.folderBox.blockSignals(False) def updateCurrentFolder(self, index): if index < self.folderBox.count() - 1: return path = QFileDialog.getExistingDirectory( self, self.tr("Choose Directory"), self.currentFolder(), QFileDialog.ShowDirsOnly) if path: QSettings().setValue("scripting/path", path) self.setCurrentFolder(path)
class DirectoryTree(QTreeView): def __init__(self): """ create directory tree """ super().__init__() self.layout = QHBoxLayout(self) self.model = QFileSystemModel() self.setModel(self.model) self.model.setRootPath(QDir.rootPath()) self.setIndentation(10) for i in range(1, 4): self.hideColumn(i) self.doubleClicked.connect(self.double_click) def set_root(self, path): """ set the directory the tree should index :param path: directory to index """ self.setRootIndex(self.model.index(path)) def double_click(self, signal): """ open a file when double clicked """ file_path = self.model.filePath(signal) tabs.tabs.new_tab(file_path)
class FileTree(QWidget): def __init__(self, defaultfolder=r'c:\Zen_Output'): super(QWidget, self).__init__() filter = ['*.czi', '*.ome.tiff', '*ome.tif' '*.tiff' '*.tif'] # define the style for the FileTree via s style sheet self.setStyleSheet(""" QTreeView::item { background-color: rgb(38, 41, 48); font-weight: bold; } QTreeView::item::selected { background-color: rgb(38, 41, 48); color: rgb(0, 255, 0); } QTreeView QHeaderView:section { background-color: rgb(38, 41, 48); color: rgb(255, 255, 255); } """) self.model = QFileSystemModel() self.model.setRootPath(defaultfolder) self.model.setFilter(QtCore.QDir.AllDirs | QDir.Files | QtCore.QDir.NoDotAndDotDot) self.model.setNameFilterDisables(False) self.model.setNameFilters(filter) self.tree = QTreeView() self.tree.setModel(self.model) self.tree.setRootIndex(self.model.index(defaultfolder)) self.tree.setAnimated(True) self.tree.setIndentation(20) self.tree.setSortingEnabled(False) header = self.tree.header() header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) windowLayout = QVBoxLayout() windowLayout.addWidget(self.tree) self.setLayout(windowLayout) self.tree.clicked.connect(self.on_treeView_clicked) @pyqtSlot() def on_treeView_clicked(self, index): indexItem = self.model.index(index.row(), 0, index.parent()) filename = self.model.fileName(indexItem) filepath = self.model.filePath(indexItem) # open the file when clicked print('Opening ImageFile : ', filepath) open_image_stack(filepath)
class RDFNavigatorProjectStructure(QWidget, Ui_ProjectStructureWidget): open_file_request = pyqtSignal(str, int) def __init__( self, parent=None, ): super(RDFNavigatorProjectStructure, self).__init__(parent) self.setupUi(self) self.basicStructureWidget.itemDoubleClicked.connect( self.createOpenFileRequest) self.childType = None self.objectsStructureModel = RDFNavigatorObjectsDomModel( QDomDocument(), self) self.objectsStructureView.setModel(self.objectsStructureModel) def createProjectTree(self, fileName, graph, childType): def createProjectTreeHelper(fileName, graph, root): for i in graph[fileName]: item = QTreeWidgetItem(root) filePath = os.path.join(os.path.dirname(fileName), i) item.setText(0, i) item.setData(0, Qt.UserRole, filePath) item.setIcon(0, QIcon(':/images/xsd.png')) createProjectTreeHelper(filePath, graph, item) self.childType = childType root = QTreeWidgetItem(self.basicStructureWidget) root.setText(0, os.path.basename(fileName)) root.setData(0, Qt.UserRole, fileName) root.setIcon(0, QIcon(':/images/xsd.png')) createProjectTreeHelper(fileName, graph, root) def createOpenFileRequest(self, item, column): self.open_file_request.emit(item.data(0, Qt.UserRole), self.childType) def createObjectsTree(self, filePath): if os.path.exists(filePath): f = QFile(filePath) if f.open(QIODevice.ReadOnly): document = QDomDocument() if document.setContent(f): newModel = RDFNavigatorObjectsDomModel(document, self) self.objectsStructureView.setModel(newModel) self.objectsStructureModel = newModel f.close() def createFileSystemTree(self, filePath): self.filesystemModel = QFileSystemModel(self) self.filesystemModel.setRootPath(os.path.dirname(filePath)) self.filesystemTreeView.setModel(self.filesystemModel) map(self.filesystemTreeView.hideColumn, range(1, 4)) def on_filesystemTreeView_doubleClicked(self, index): file_path = self.filesystemModel.filePath(index) self.open_file_request.emit(file_path, self.childType)
class CommanderFileManager(object): """docstring for FileManager""" def __init__(self): self.files_tree_model = QFileSystemModel() self.set_filter() self.files_tree_model.setRootPath(os.path.abspath(__file__)) self._file = None def set_filter(self, filter_list=['*.lua']): self.files_tree_model.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot | QDir.AllEntries) self.files_tree_model.setNameFilters(filter_list) self.files_tree_model.setNameFilterDisables(0) def get_path(self, index): return self.files_tree_model.filePath(index) def open(self, path): try: with open(path, 'rt') as f: text = f.read() self._file = path return text except Exception as e: print(e) return None def save(self, fp, text): """ save file document """ try: with open(fp, 'wt') as f: f.write(text) except Exception as e: return False return True @property def file(self): return self._file @file.setter def file(self, f): self._file = f
class App(QWidget): def __init__(self): super().__init__() self.title = 'PyQt5 file system view - pythonspot.com' 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('/home/rob/Muziek') filter = ["*.wav", "*.ogg"] self.model.setNameFilters(filter) self.model.setNameFilterDisables(0) root = self.model.setRootPath('/home/rob/Muziek') #print(root) self.tree = QTreeView() self.tree.setModel(self.model) self.tree.setRootIndex(root) self.tree.setAnimated(False) self.tree.setIndentation(20) self.tree.setSortingEnabled(True) self.tree.doubleClicked.connect(self.test) self.tree.setWindowTitle("Dir View") self.tree.resize(640, 480) windowLayout = QVBoxLayout() windowLayout.addWidget(self.tree) self.setLayout(windowLayout) self.show() def test(self, signal): file_path = self.model.filePath(signal) print(file_path)
class SelectFolderWindow(QtGui.QDialog, Ui_Session_Dialog): def __init__(self, directory, parent=None): super(SelectFolderWindow, self).__init__(parent) self.setupUi(self) self.folder_name = None self.folder_path = None self.file_model = QFileSystemModel() self.directory = directory self.file_model.setRootPath(directory) self.folder_tree.setModel(self.file_model) self.folder_tree.setRootIndex(self.file_model.index(self.directory)) self.folder_tree.clicked.connect(self.set_session_folder) def update_file_model(self, new_dir): self.directory = new_dir self.file_model.setRootPath(new_dir) def set_session_folder(self, index): indexItem = self.file_model.index(index.row(), 0, index.parent()) self.folder_name = self.file_model.fileName(indexItem) self.folder_path = self.file_model.filePath(indexItem) self.selected_session.setText(self.folder_path)
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建Ui对象 self.ui.setupUi(self) #构造UI self.LabPath = QLabel(self) self.ui.statusBar.addWidget(self.LabPath) self.__buildModelView() ##==========自定义功能函数========== def __buildModelView(self): self.model = QFileSystemModel(self) #定义数据模型 self.model.setRootPath(QDir.currentPath()) #获取当前路径,并设置为model的根目录 self.ui.treeView.setModel(self.model) #将self.model设置为自己的数据模型 self.ui.listView.setModel(self.model) self.ui.tableView.setModel(self.model) #将treeView的cilcked信号与listView与tableView的槽函数setRootIndex相关联 self.ui.treeView.clicked.connect(self.ui.listView.setRootIndex) self.ui.treeView.clicked.connect(self.ui.tableView.setRootIndex) ##==========事件处理函数=========== ##==========由connectSlotsByName()自动关联的槽函数==== def on_treeView_clicked(self, index): #index是模型索引 print(index) self.ui.checkBox.setChecked(self.model.isDir(index)) self.LabPath.setText(self.model.filePath(index)) self.ui.LabType.setText(self.model.type(index)) self.ui.LabFileName.setText(self.model.fileName(index)) fileSize = self.model.size(index) / 1024 # print(fileSize) if fileSize < 1024: self.ui.LabFileSize.setText("%d KB" % fileSize) else: self.ui.LabFileSize.setText(".2f MB" % (fileSize / 1024.0))
class ImageViewer(QtWidgets.QMainWindow, Ui_ImageViewer): def __init__(self, folder_path, configuration, parent=None): super(ImageViewer, self).__init__(parent) self.folder_path = folder_path self.image_size = configuration[0].split("x") self.setupUi(self) self.width = int(self.image_size[0]) self.height = int(self.image_size[1]) self.aspect_ratio = (self.height / self.width) * 900 self.resize(900 + 211, int(self.aspect_ratio)) self.label.setGeometry(QtCore.QRect(211, -5, 900, int(self.aspect_ratio))) self.model = QFileSystemModel() self.model.setRootPath(QDir.currentPath()) self.folder_view.setModel(self.model) self.folder_view.setRootIndex(self.model.index(self.folder_path)) self.folder_view.selectionModel().selectionChanged.connect(self.file_details) self.folder_view.setGeometry(QtCore.QRect(0, 0, 211, int(self.aspect_ratio))) def file_details(self): index = self.folder_view.currentIndex() image = self.model.filePath(index) self.label.setPixmap(QPixmap(image))
class SearchDir(QWidget): def __init__(self): super().__init__() self.title = '' self.initUI() def initUI(self): self.model = QFileSystemModel() self.model.setRootPath('') self.tree = QTreeView() self.tree.setModel(self.model) self.tree.setAnimated(False) self.tree.setIndentation(20) self.tree.setSortingEnabled(True) windowLayout = QVBoxLayout() windowLayout.addWidget(self.tree) self.setLayout(windowLayout) self.show() def getPath(self): index = self.tree.currentIndex() return self.model.filePath(index)
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 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 FileBrowser(QDialog): def __init__(self, state, path): """ Настройка UI :param state: state :param path: путь до первоначальной директории """ super(FileBrowser, self).__init__() uic.loadUi("ui/filebrowser.ui", self) self.toolButton.setArrowType(QtCore.Qt.UpArrow) self.toolButton.clicked.connect(self.dir_up) self.openButton.clicked.connect(self.open_action) self.state = state self.path = path self.populate() def populate(self): """ Настраивает treeView """ self.treeView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.treeView.customContextMenuRequested.connect(self.context_menu) self.treeView.doubleClicked.connect(self.double_click) self.model = QFileSystemModel() self.model.setRootPath((QtCore.QDir.rootPath())) self.treeView.setModel(self.model) self.set_treeView_path(self.path) self.treeView.selectionModel().selectionChanged.connect(self.select) self.treeView.setSortingEnabled(True) def context_menu(self): """ Отображает контекстное меню по ПКМ """ menu = QMenu() open_action = menu.addAction("Выбрать") open_action.triggered.connect(self.open_action) if os.path.isfile(self.get_path()): show_text = menu.addAction("Показать текст") show_text.triggered.connect(self.show_text) cursor = QtGui.QCursor() menu.exec_(cursor.pos()) def get_path(self): """ Возвращает путь до выбранного файла :return: str """ index = self.treeView.currentIndex() return self.model.filePath(index) def set_treeView_path(self, path): """ Устанавливает директорию, отображаемую treeView :param path: str """ self.path = path self.treeView.setRootIndex(self.model.index(path)) self.pathField.setText(path) def open_action(self): """ Выбирает midi файл для вопсроизведения """ path = ( self.get_path() if not self.last_selected else self.last_selected ) if not self.check_path(path): return self.state.file = path self.close() def double_click(self): """ Обработчки двойного клика на файл """ path = self.get_path() if os.path.isfile(path): self.open_action() else: self.set_treeView_path(path) def dir_up(self): """ Обработчки кнопки перехода к директории верхнего уровня """ self.set_treeView_path(os.path.dirname(self.path)) def select(self): """ Обработчик выделения """ path = self.get_path() if os.path.isfile(path): self.last_selected = path self.fileField.setText(path) self.openButton.setEnabled(True) def check_path(self, path): """ Проверяет, является файл по пути path валидным midi файлом :param path: str """ if not is_midi_file(path): errorBox = QMessageBox() errorBox.setText("Файл не является midi файлом") errorBox.setIcon(QMessageBox.Critical) errorBox.exec() return False return True def show_text(self): """ Открывает диалоговое окно с тектом песни """ path = ( self.get_path() if not self.last_selected else self.last_selected ) if not self.check_path(path): return parser = Parser(path) text = parser.parse()[1] msgBox = QMessageBox() msgBox.setText("\n".join(text)) msgBox.exec()
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 MyMainWindow(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.config_window() self.create_widgets() self.config_widgets() self.create_menubar() self.bind_widgets() self.show_widgets() def config_window(self): self.setWindowTitle('DirectoPy') self.setMinimumHeight(600) self.setMinimumWidth(1000) def create_widgets(self): self.central_widget = QWidget() self.main_layout = QGridLayout() self.moveup_button = QPushButton('Collapse all', self) self.goto_lineedit = QLineEdit('', self) self.goto_button = QPushButton('Go', self) self.folder_view = QTreeView(self) self.file_view = QTreeView(self) self.folder_model = QFileSystemModel(self) self.file_model = QFileSystemModel(self) def config_widgets(self): self.main_layout.addWidget(self.moveup_button, 0, 0) self.main_layout.addWidget(self.goto_lineedit, 0, 1, 1, 2) self.main_layout.addWidget(self.goto_button, 0, 3) self.main_layout.addWidget(self.folder_view, 1, 0, 1, 2) self.main_layout.addWidget(self.file_view, 1, 2, 1, 2) self.central_widget.setLayout(self.main_layout) # Кнопка "вверх" self.moveup_button.setMaximumWidth(100) # Кнопка "перейти" self.goto_button.setMaximumWidth(70) self.setCentralWidget(self.central_widget) # панели self.folder_model.setRootPath(None) self.folder_model.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot) self.folder_view.setModel(self.folder_model) self.folder_view.setRootIndex(self.folder_model.index(None)) self.folder_view.clicked[QModelIndex].connect(self.clicked_onfolder) self.folder_view.hideColumn(1) self.folder_view.hideColumn(2) self.folder_view.hideColumn(3) self.file_model.setFilter(QDir.Files) self.file_view.setModel(self.file_model) self.file_model.setReadOnly(False) self.file_view.setColumnWidth(0, 200) self.file_view.setSelectionMode(QAbstractItemView.ExtendedSelection) # открытие папки при нажати на неё в окне папок def clicked_onfolder(self, index): selection_model = self.folder_view.selectionModel() index = selection_model.currentIndex() dir_path = self.folder_model.filePath(index) self.file_model.setRootPath(dir_path) self.file_view.setRootIndex(self.file_model.index(dir_path)) # ф-я открытия нового файла def open_file(self): index = self.file_view.selectedIndexes() if not index: return else: index = index[0] file_path = self.file_model.filePath(index).replace('/', '\\') print(file_path) self.file_view.update() # ф-я создания нового файла def new_file(self): global file_name index = self.folder_view.selectedIndexes() if len(index) > 0: path = self.folder_model.filePath(index[0]) for i in range(1, 9999999999999999): if not os.path.isfile(os.path.join(path, "newfile{}.txt".format(i))): file_name = os.path.join(path, "newfile{}.txt".format(i)) break file_name = os.path.abspath(file_name) open(file_name, 'w').close() else: print("Please, select folder") # ф-я удаления файла def delete_file(self): indexes = self.file_view.selectedIndexes() for i in indexes: self.file_model.remove(i) # ф-я переименования файла def rename_file(self): index = self.file_view.selectedIndexes() if not index: return else: index = index[0] self.file_view.edit(index) # ф-я копирования файла def copy_file(self): print("COPY") ask = QFileDialog.getExistingDirectory(self, "Open Directory", "C:\\", QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks) new_path = ask.replace('\\', '/') indexes = self.file_view.selectedIndexes()[::4] for i in indexes: new_filename = new_path + '/' + self.file_model.fileName(i) copy2(self.file_model.filePath(i), new_filename) # ф-я возвращения к корню пути def colapse(self): self.folder_view.collapseAll() # ф-я перемещения в заданную директорию def go_to(self): dir_path = self.goto_lineedit.text().replace('\\', '/') print(dir_path) self.file_model.setRootPath(dir_path) self.file_view.setRootIndex(self.file_model.index(dir_path)) #self.file_model.setRootPath() # ф-я перемещения файла def move_file(self): print("MOVE") ask = QFileDialog.getExistingDirectory(self, "Open Directory", "C:\\", QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks) if ask == '': return new_path = ask.replace('\\', '/') indexes = self.file_view.selectedIndexes()[::4] for i in indexes: new_filename = new_path + '/' + self.file_model.fileName(i) move(self.file_model.filePath(i), new_filename) # ф-я создания новой папки def new_folder(self): global file_name index = self.folder_view.selectedIndexes() if len(index) > 0: path = self.folder_model.filePath(index[0]) for i in range(1, 9999999999999999): if not os.path.isdir(os.path.join(path, "newfolder{}".format(i))): file_name = os.path.join(path, "newfolder{}".format(i)) break file_name = os.path.abspath(file_name) os.mkdir(file_name) else: print("Please, select folder") # ф-я удаления папки def delete_folder(self): indexes = self.folder_view.selectedIndexes() for i in indexes: self.folder_model.remove(i) # ф-я переименования папки def rename_folder(self): index = self.folder_view.selectedIndexes() if not index: return else: index = index[0] self.folder_view.edit(index) # ф-я закрытия окна файлового менеджера def exit_application(self): print("EXIT") self.close() # задавание функции каждой кнопке def bind_widgets(self): self.open_file_action.triggered.connect(self.open_file) self.new_file_action.triggered.connect(self.new_file) self.delete_file_action.triggered.connect(self.delete_file) self.rename_file_action.triggered.connect(self.rename_file) self.copy_file_action.triggered.connect(self.copy_file) self.move_file_action.triggered.connect(self.move_file) self.exit_action.triggered.connect(self.exit_application) self.new_folder_action.triggered.connect(self.new_folder) self.delete_folder_action.triggered.connect(self.delete_folder) self.rename_folder_action.triggered.connect(self.rename_folder) self.goto_button.clicked.connect(partial(self.go_to)) self.moveup_button.clicked.connect(partial(self.colapse)) # создание меню def create_menubar(self): self.exit_action = QAction('Exit', self) self.exit_action.setShortcut('Ctrl+Q') self.new_file_action = QAction('New file', self) self.new_file_action.setShortcut('F4') self.open_file_action = QAction('Open file', self) self.open_file_action.setShortcut('F3') self.rename_file_action = QAction('Rename file', self) self.rename_file_action.setShortcut('F2') self.delete_file_action = QAction('Remove file', self) self.delete_file_action.setShortcut(QKeySequence.Delete) self.copy_file_action = QAction('Copy folder...', self) self.copy_file_action.setShortcut(QKeySequence.Copy) self.move_file_action = QAction('Move folder...', self) self.move_file_action.setShortcut(QKeySequence.Cut) self.new_folder_action = QAction('New folder', self) self.new_folder_action.setShortcut('Ctrl+Shift+N') self.delete_folder_action = QAction('Delete folder', self) self.delete_folder_action.setShortcut('Ctrl+Shift+Del') self.rename_folder_action = QAction('Rename folder', self) self.rename_folder_action.setShortcut('Ctrl+Shift+R') self.menubar = self.menuBar() self.file_menu = self.menubar.addMenu('File') self.file_menu.addAction(self.new_file_action) self.file_menu.addAction(self.open_file_action) self.file_menu.addAction(self.rename_file_action) self.file_menu.addAction(self.delete_file_action) self.file_menu.addAction(self.copy_file_action) self.file_menu.addAction(self.move_file_action) self.file_menu.addSeparator() self.file_menu.addAction(self.exit_action) self.folder_menu = self.menubar.addMenu('Folder') self.folder_menu.addAction(self.new_folder_action) self.folder_menu.addAction(self.delete_folder_action) self.folder_menu.addAction(self.rename_folder_action) def show_widgets(self): self.setLayout(self.main_layout)
class MainView(QMainWindow): resizeCompleted = pyqtSignal() def __init__(self, model, controller, image_path): self.settings = SettingsModel() self.slideshow = SlideshowModel() self.model = model self.canvas = self.model.canvas self.main_controller = controller self.canvas_controller = CanvasController(self.canvas) super(MainView, self).__init__() self.build_ui() self.center_ui() # Resize timer to prevent laggy updates self.resize_timer = None self.resizeCompleted.connect(self.resize_completed) # Slideshow if self.settings.get('Slideshow', 'reverse') == 'True': self.slideshow.updateSignal.connect(self.on_previous_item) else: self.slideshow.updateSignal.connect(self.on_next_item) self.model.subscribe_update_func(self.update_ui_from_model) self.arguments = { 'image_path': image_path } def build_ui(self): self.ui = Ui_Hitagi() self.ui.setupUi(self) # File menu self.ui.actionSet_as_wallpaper.triggered.connect(self.on_set_as_wallpaper) self.ui.actionCopy_to_clipboard.triggered.connect(self.on_clipboard) self.ui.actionOpen_current_directory.triggered.connect(self.on_current_dir) self.ui.actionOptions.triggered.connect(self.on_options) self.ui.actionExit.triggered.connect(self.on_close) # Folder menu self.ui.actionOpen_next.triggered.connect(self.on_next_item) self.ui.actionOpen_previous.triggered.connect(self.on_previous_item) self.ui.actionChange_directory.triggered.connect(self.on_change_directory) self.ui.actionSlideshow.triggered.connect(self.on_slideshow) # View menu self.ui.actionZoom_in.triggered.connect(self.on_zoom_in) self.ui.actionZoom_out.triggered.connect(self.on_zoom_out) self.ui.actionOriginal_size.triggered.connect(self.on_zoom_original) self.ui.actionRotate_clockwise.triggered.connect(self.on_rotate_clockwise) self.ui.actionRotate_counterclockwise.triggered.connect(self.on_rotate_counterclockwise) self.ui.actionFlip_horizontally.triggered.connect(self.on_flip_horizontal) self.ui.actionFlip_vertically.triggered.connect(self.on_flip_vertical) self.ui.actionFit_image_width.triggered.connect(self.on_scale_image_to_width) self.ui.actionFit_image_height.triggered.connect(self.on_scale_image_to_height) self.ui.actionFile_list.triggered.connect(self.on_toggle_filelist) self.ui.actionFullscreen.triggered.connect(self.on_fullscreen) # Favorite menu self.ui.actionAdd_to_favorites.triggered.connect(self.on_add_to_favorites) self.ui.actionRemove_from_favorites.triggered.connect(self.on_remove_from_favorites) # Help menu self.ui.actionChangelog.triggered.connect(self.on_changelog) self.ui.actionAbout.triggered.connect(self.on_about) # Load stylesheet stylesheet_dir = "resources/hitagi.stylesheet" with open(stylesheet_dir, "r") as sh: self.setStyleSheet(sh.read()) # File listing self.file_model = QFileSystemModel() self.file_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs | QDir.Files) self.file_model.setNameFilters(['*.bmp', '*.gif', '*.jpg', '*.jpeg', '*.png', '*.png', '*.pbm', '*.pgm', '*.ppm', '*.xbm', '*.xpm']) self.file_model.setNameFilterDisables(False) self.file_model.setRootPath(self.settings.get('Directory', 'default')) self.ui.treeView.setModel(self.file_model) self.ui.treeView.setColumnWidth(0, 120) self.ui.treeView.setColumnWidth(1, 120) self.ui.treeView.hideColumn(1) self.ui.treeView.hideColumn(2) # Double click self.ui.treeView.activated.connect(self.on_dir_list_activated) # Update file list self.ui.treeView.clicked.connect(self.on_dir_list_clicked) # Open parent self.ui.pushButton_open_parent.clicked.connect(self.on_open_parent) self.ui.pushButton_favorite.clicked.connect(self.on_manage_favorite) # Shortcuts _translate = QCoreApplication.translate self.ui.actionExit.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Exit'))) self.ui.actionOpen_next.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Next'))) self.ui.actionOpen_previous.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Previous'))) self.ui.actionChange_directory.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Directory'))) self.ui.actionAdd_to_favorites.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Add to favorites'))) self.ui.actionRemove_from_favorites.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Remove from favorites'))) self.ui.actionSlideshow.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Slideshow'))) self.ui.actionZoom_in.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Zoom in'))) self.ui.actionZoom_out.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Zoom out'))) self.ui.actionOriginal_size.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Zoom original'))) self.ui.actionRotate_clockwise.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Rotate clockwise'))) self.ui.actionRotate_counterclockwise.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Rotate counterclockwise'))) self.ui.actionFlip_horizontally.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Flip horizontal'))) self.ui.actionFlip_vertically.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Flip vertical'))) self.ui.actionFit_image_width.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Fit to width'))) self.ui.actionFit_image_height.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Fit to height'))) self.ui.actionFile_list.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Toggle filelist'))) self.ui.actionFullscreen.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Fullscreen'))) # Load favorites in UI self.load_favorites() # Background self.ui.graphicsView.setBackgroundBrush(QBrush(QColor(self.settings.get('Look', 'background')), Qt.SolidPattern)) # Save current height for fullscreen mode self.default_menubar_height = self.ui.menubar.height() # Save current width for file list self.default_filelist_width = self.ui.fileWidget.width() def load_favorites(self): self.favorites = FavoritesModel() self.ui.menuFavorites.clear() for item in self.favorites.items(): self.ui.menuFavorites.addAction(item).triggered.connect((lambda item: lambda: self.on_open_favorite(item))(item)) def on_open_favorite(self, path): self.main_controller.change_directory(path) def center_ui(self): ui_geometry = self.frameGeometry() center_point = QDesktopWidget().availableGeometry().center() ui_geometry.moveCenter(center_point) self.move(ui_geometry.topLeft()) # Qt show event def showEvent(self, event): self.main_controller.start(self.arguments['image_path']) # Arguments and starting behaviour # Start in fullscreen mode according to settings if self.settings.get('Misc', 'fullscreen_mode') == 'True': self.on_fullscreen() # Initialize container geometry to canvas self.canvas_controller.update(self.ui.graphicsView.width(), self.ui.graphicsView.height()) self.main_controller.update_canvas() def update_resize_timer(self, interval=None): if self.resize_timer is not None: self.killTimer(self.resize_timer) if interval is not None: self.resize_timer = self.startTimer(interval) else: self.resize_timer = None # Qt resize event def resizeEvent(self, event): self.update_resize_timer(300) # Qt timer event def timerEvent(self, event): if event.timerId() == self.resize_timer: self.update_resize_timer() self.resizeCompleted.emit() def resize_completed(self): self.canvas_controller.update(self.ui.graphicsView.width(), self.ui.graphicsView.height()) self.main_controller.update_canvas() # Additional static shortcuts def keyPressEvent(self, e): if e.key() == Qt.Key_Escape and self.model.is_fullscreen: self.main_controller.toggle_fullscreen() def on_open_parent(self): parent_index = self.file_model.parent(self.file_model.index(self.file_model.rootPath())) self.file_model.setRootPath(self.file_model.filePath(parent_index)) self.ui.treeView.setRootIndex(parent_index) # Update directory path self.model.directory = self.file_model.filePath(parent_index) self.update_ui_from_model() def on_dir_list_activated(self, index): if self.file_model.isDir(index) is not False: self.file_model.setRootPath(self.file_model.filePath(index)) self.ui.treeView.setRootIndex(index) # Save current path self.model.directory = self.file_model.filePath(index) self.update_ui_from_model() def on_dir_list_clicked(self, index): self.main_controller.open_image(self.file_model.filePath(index)) # File menu def on_set_as_wallpaper(self): from hitagilib.view.WallpaperView import WallpaperDialog from hitagilib.controller.wallpaper import WallpaperController image = self.model.get_image() if image is not None: dialog = WallpaperDialog(self, None, WallpaperController(self.model), image) dialog.show() def on_clipboard(self): self.main_controller.copy_to_clipboard() def on_current_dir(self): if not self.main_controller.open_in_explorer(): self.show_explorer_error() def on_options(self): from hitagilib.view.OptionsView import OptionDialog self.dialog = OptionDialog(self) self.dialog.show() def on_close(self): if self.slideshow.isRunning(): self.slideshow.exit() self.close() # Folder menu def on_next_item(self): current_index = self.ui.treeView.currentIndex() # Slideshow restart - determine if we are at the end of our file list if self.slideshow.is_running and self.settings.get('Slideshow', 'restart') == 'True' and not self.ui.treeView.indexBelow(current_index).isValid(): self.main_controller.open_image(self.file_model.filePath(current_index)) self.on_slideshow_restart(0) # Restart slideshow elif self.slideshow.is_running and self.settings.get('Slideshow', 'random') == 'True': # Random index - moveCursor expects constants @http://doc.qt.io/qt-5/qabstractitemview.html#CursorAction-enum index = self.ui.treeView.moveCursor(randint(0,9), Qt.NoModifier) self.ui.treeView.setCurrentIndex(index) self.main_controller.open_image(self.file_model.filePath(index)) else: # Proceed normally, scroll down index = self.ui.treeView.moveCursor(QAbstractItemView.MoveDown, Qt.NoModifier) self.ui.treeView.setCurrentIndex(index) self.main_controller.open_image(self.file_model.filePath(index)) def on_previous_item(self): current_index = self.ui.treeView.currentIndex() # Slideshow restart (reverse) - determine if we are the the top of our file list if self.slideshow.is_running and self.settings.get('Slideshow', 'restart') == 'True' and not self.ui.treeView.indexAbove(current_index).isValid(): self.main_controller.open_image(self.file_model.filePath(current_index)) self.on_slideshow_restart(1) # Restart slideshow elif self.slideshow.is_running and self.settings.get('Slideshow', 'random') == 'True': # Random index index = self.ui.treeView.moveCursor(randint(0,9), Qt.NoModifier) self.ui.treeView.setCurrentIndex(index) self.main_controller.open_image(self.file_model.filePath(index)) else: # Proceed normally, scroll up index = self.ui.treeView.moveCursor(QAbstractItemView.MoveUp, Qt.NoModifier) self.ui.treeView.setCurrentIndex(index) self.main_controller.open_image(self.file_model.filePath(index)) def on_slideshow(self): if self.ui.actionSlideshow.isChecked(): self.slideshow.start() self.slideshow.is_running = True else: self.slideshow.is_running = False self.slideshow.exit() def on_slideshow_restart(self, direction): # 0: Restart from top to bottom # 1: Restart from bottom to top if direction == 0: index = self.ui.treeView.moveCursor(QAbstractItemView.MoveHome, Qt.NoModifier) self.main_controller.open_image(self.file_model.filePath(index)) else: index = self.ui.treeView.moveCursor(QAbstractItemView.MoveEnd, Qt.NoModifier) self.main_controller.open_image(self.file_model.filePath(index)) self.ui.treeView.setCurrentIndex(index) def on_change_directory(self): self.main_controller.change_directory() # View menu def on_zoom_in(self): self.canvas_controller.scale_image(1.1) def on_zoom_out(self): self.canvas_controller.scale_image(0.9) def on_rotate_clockwise(self): self.canvas_controller.rotate_image(90) def on_rotate_counterclockwise(self): self.canvas_controller.rotate_image(-90) def on_flip_horizontal(self): self.canvas_controller.flip_image(0) def on_flip_vertical(self): self.canvas_controller.flip_image(1) def on_scale_image_to_width(self): self.canvas_controller.update_image(1) def on_scale_image_to_height(self): self.canvas_controller.update_image(2) def on_zoom_original(self): self.canvas_controller.update_image(3) def on_toggle_filelist(self): if self.ui.fileWidget.isHidden(): self.ui.fileWidget.show() else: self.ui.fileWidget.hide() self.update_resize_timer(300) def on_fullscreen(self): self.main_controller.toggle_fullscreen() if self.model.is_fullscreen: self.showFullScreen() if self.settings.get('Misc', 'hide_menubar') == 'True': self.ui.menubar.setMaximumHeight(0) # Workaround to preserve shortcuts else: self.showNormal() if self.settings.get('Misc', 'hide_menubar') == 'True': self.ui.menubar.setMaximumHeight(self.default_menubar_height) self.canvas_controller.update(self.ui.graphicsView.width(), self.ui.graphicsView.height()) self.main_controller.update_canvas() # Favorite button def on_manage_favorite(self): if self.main_controller.check_favorites(self.model.directory): self.on_remove_from_favorites() else: self.on_add_to_favorites() # Favorite menu def on_add_to_favorites(self): self.main_controller.add_to_favorites() self.load_favorites() self.update_ui_from_model() def on_remove_from_favorites(self): self.main_controller.remove_from_favorites() self.load_favorites() self.update_ui_from_model() # Help menu def on_changelog(self): webbrowser.open('https://github.com/gimu/hitagi-reader/releases') def on_about(self): from hitagilib.view.AboutView import AboutDialog dialog = AboutDialog(self, None, None) dialog.show() def on_fileWidget_visibilityChanged(self, visible): """On file list hide/show and de/attachment""" if visible: self.ui.actionFile_list.setChecked(True) else: self.ui.actionFile_list.setChecked(False) self.update_resize_timer(300) def show_explorer_error(self): notify = QMessageBox() notify.setWindowTitle("Error") notify.setText(QCoreApplication.translate('Hitagi', "Couldn't open the current directory with an appropriate filemanager!")) notify.exec_() def update_ui_from_model(self): """Update UI from model.""" self.settings = SettingsModel() # On changing directory self.file_model.setRootPath(self.model.directory) self.ui.treeView.setRootIndex(self.file_model.index(self.model.directory)) # Update favorite button if self.main_controller.check_favorites(self.model.directory): self.ui.pushButton_favorite.setText(QCoreApplication.translate('Hitagi', "Unfavorite")) else: self.ui.pushButton_favorite.setText(QCoreApplication.translate('Hitagi', "Favorite")) # Canvas update self.ui.graphicsView.setScene(self.canvas.scene)
class miFormulario(QMainWindow,QDialog): path='' enPlay2={} enDirectorio=[] def __init__(self, parent=None): QtWidgets.QWidget.__init__(self,parent) self.ui=Ui_MainWindow() self.ui.setupUi(self) self.ui.btnNuevaCancion.clicked.connect(self.nuevaCancion) self.ui.btnAgregarSet.clicked.connect(self.agregar_a_play) self.ui.listaCanciones.doubleClicked.connect(self.agregar_a_play) self.ui.btnQuitarSet.clicked.connect(self.borrarItemListaPlay) self.ui.btnPlay.clicked.connect(self.abrirCancion) self.ui.listaPlay.doubleClicked.connect(self.abrirCancion) self.ui.btnGuardarCancion.clicked.connect(self.guardarCambios) self.ui.btnSubir.clicked.connect(self.transportarArriba) self.ui.btnBajar.clicked.connect(self.transportarAbajo) self.ui.btnExportarPDF.clicked.connect(self.exportarPDF) self.ui.btnGuardarSet.clicked.connect(self.guardarSet) self.ui.btnCargarSet.clicked.connect(self.cargarLista) self.ui.btnAbrirDirectorio.clicked.connect(self.abrirBrwserCarpetas) self.ui.btnAbrirCancion.clicked.connect(self.abrirUnaCancion) def abrirBrwserCarpetas(self): self.ventana=QtWidgets.QDialog() self.ui2=Ui_Directorio() self.ui2.setupUi(self.ventana) self.ventana.show() homedir = os.path.expanduser("~") self.model = QFileSystemModel() self.model.setFilter(QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Dirs | QtCore.QDir.NoSymLinks) self.model.setRootPath(QtCore.QDir.rootPath()) self.tree = self.ui2.vistaDirectorio self.tree.setModel(self.model) self.tree.setRootIndex(self.model.index(homedir)) self.ui2.btnAbrirCarpeta.clicked.connect(self.rutaCarpeta) self.ui2.btnCancelarBrowser.clicked.connect(self.cerrarBrowser) def rutaCarpeta(self): index=self.ui2.vistaDirectorio.currentIndex() self.path=self.model.filePath(index) self.abrirDirectorio() def cerrarBrowser(self): self.ventana.close() def closeEvent(self, event): respuesta = QMessageBox.question(self, 'Cerra Aplicación', "Está seguro que quiere cerrar la aplicación", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if respuesta == QMessageBox.Yes: event.accept() else: event.ignore() def abrirDirectorio(self): self.enDirectorio=[] self.ui.listaCanciones.clear() files=[] for r, d, f in os.walk(self.path): #@UnusedVariable for file in f: if file[-4:]=='.cec': files.append(file) self.enDirectorio.append((r+'/'+file)) for f in files: self.ui.listaCanciones.addItem(f.strip('.cec')) if files!=[]: self.cerrarBrowser() if files==[]: QMessageBox.information(self, 'Error', 'Esta carpeta no contiene canciones para abrir') def abrirUnaCancion(self): try: homedir = os.path.expanduser("~") ruta=homedir+'\Desktop' path,_=QFileDialog.getOpenFileName(self, 'Seleccionar Canción', ruta) nombre=QFileInfo(path).fileName() if path[-4:]=='.cec': self.enDirectorio.append(path) self.ui.listaCanciones.addItem(nombre.strip('.cec')) except: pass def nuevaCancion(self): self.ui.cancionTE.clear() self.ui.cancionTE2.clear() self.ui.cancionTE.setPlaceholderText('''Escribir o pegar la cancion que desee guardar aquí recuerde que los reglones de las notas deben comensar con un punto (.) en el margen izquierdo y las tono principal deben estar en mayúscula y el resto del acorde en minúsculas. Ej: TITULO (si lo desea) AUTOR (si lo desea) ALGUNA OBSERVACIÓN (si lo desea) INTRO: .A Dm G# .C G Ebm Mi corazón confiado está por que yo te conozco . Emaj7 F# Gm/D Y en medio de la tempestad nunca estoy solo ''') def agregar_a_play(self): try: fila=self.ui.listaCanciones.currentRow() lista=self.ui.listaCanciones.selectedItems() for l in lista: self.enPlay2[l.text()]=self.enDirectorio[fila]+'\n' self.ui.listaPlay.addItem(l.text()) except: QMessageBox.information(self, 'Error','Error al cargar a Play List') def borrarItemListaPlay(self): try: lista=self.ui.listaPlay.selectedItems() self.ui.listaPlay.takeItem(self.ui.listaPlay.currentRow()) for l in lista: del self.enPlay2[l.text()] except: QMessageBox.information(self, 'Quitar', 'No hay nada para quitar') def abrirCancion(self): try: self.ui.cancionTE.clear() self.ui.cancionTE2.clear() lista=self.ui.listaPlay.selectedItems() for l in lista: file_text=abrirCancionSeleccionada(self.enPlay2[l.text()].strip('\n')) self.abrirConFormato(file_text) except: QMessageBox.information(self, 'Error', 'Verifique que la canción no se haya movido de carpeta') def guardarCambios(self): homedir = os.path.expanduser("~") ruta=homedir+'\Desktop' try: texto2 = self.ui.cancionTE.toPlainText() self.ui.cancionTE.clear() escribirCrearArchivo(texto2) file_text=abrirAuxiliar() for f in file_text: if f[0]=='.': self.ui.cancionTE.setTextColor(QtGui.QColor("blue")) self.ui.cancionTE.setFontWeight(QtGui.QFont.Bold) self.ui.cancionTE.setFontPointSize(10) self.ui.cancionTE.append(f.strip('\n')) if f[0]!='.': if f[0]!=' ': self.ui.cancionTE.setTextColor(QtGui.QColor("black")) self.ui.cancionTE.setFontWeight(QtGui.QFont.Bold) self.ui.cancionTE.setFontPointSize(10) self.ui.cancionTE.append(' '+f.strip('\n')) if f[0]==' ': self.ui.cancionTE.setTextColor(QtGui.QColor("black")) self.ui.cancionTE.setFontWeight(QtGui.QFont.Bold) self.ui.cancionTE.setFontPointSize(10) self.ui.cancionTE.append(f.strip('\n')) filename, _ = QFileDialog.getSaveFileName(self, 'Save File', ruta) if filename !='': if QFileInfo(filename).suffix() == '': filename += '.cec' f=open(filename, 'w') texto = self.ui.cancionTE.toPlainText()+'\n'+self.ui.cancionTE2.toPlainText() f.write(texto) f.close() except: pass def transportarArriba(self): try: cancion=abrirAuxiliar() self.ui.cancionTE.clear() self.ui.cancionTE2.clear() nuevaCancion=transportarMedioArriba(cancion) self.abrirConFormato(nuevaCancion) except: QMessageBox.information(self, 'Error','Debe guardar la canción primero o No hay nada para transportar') def transportarAbajo(self): try: cancion=abrirAuxiliar() self.ui.cancionTE.clear() self.ui.cancionTE2.clear() nuevaCancion=transportarMedioAbajo(cancion) self.abrirConFormato(nuevaCancion) except: QMessageBox.information(self, 'Error','Debe guardar la canción primero o No hay nada para transportar') def exportarPDF(self): try: self.ui.cancionTE2.clear() file_text=abrirAuxiliar() for f in file_text: if f[0]=='.': self.ui.cancionTE2.setTextColor(QtGui.QColor("blue")) self.ui.cancionTE2.setFontWeight(QtGui.QFont.Bold) self.ui.cancionTE2.setFontPointSize(10) self.ui.cancionTE2.append(f.strip('\n')) if f[0]!='.': self.ui.cancionTE2.setTextColor(QtGui.QColor("black")) self.ui.cancionTE2.setFontWeight(QtGui.QFont.Bold) self.ui.cancionTE2.setFontPointSize(10) self.ui.cancionTE2.append(f.strip('\n')) except: pass try: filename, _ = QFileDialog.getSaveFileName(self, 'Exportar a PDF', None, 'PDF files (.pdf) ;; All Files()') if filename !='': if QFileInfo(filename).suffix() == '': filename += '.pdf' printer = QPrinter(QPrinter.HighResolution) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(filename) self.ui.cancionTE2.document().print_(printer) self.ui.cancionTE.clear() self.ui.cancionTE2.clear() file_text=abrirAuxiliar() self.abrirConFormato(file_text) except: pass def guardarSet(self): homedir = os.path.expanduser("~") ruta=homedir+'\Desktop' try: enPlay={} for i in range(self.ui.listaPlay.count()): enPlay[self.ui.listaPlay.item(i).text()]=self.enPlay2[self.ui.listaPlay.item(i).text()] filename, _ = QFileDialog.getSaveFileName(self, 'Guardar Lista', ruta) if filename !='': if QFileInfo(filename).suffix() == '': filename += '.lec' f=open(filename,'w') f.writelines(str(enPlay)) f.close() except: QMessageBox.information(self, 'Error','Error al Guardar Set') def cargarLista(self): homedir = os.path.expanduser("~") ruta=homedir+'\Desktop' try: self.ui.listaPlay.clear() self.enPlay2={} filename, _ = QFileDialog.getOpenFileName(self, 'Abrir Lista', ruta) f=open(filename, 'r') file_text =f.readlines() for ft in file_text: self.enPlay2=eval(ft) for key in self.enPlay2.keys(): self.ui.listaPlay.addItem(key) except: QMessageBox.information(self, 'Error','Error al cargar Lista') def abrirConFormato(self,file_text): count=0 for f in file_text: count+=1 if count<40: if f[0]=='.': self.ui.cancionTE.setTextColor(QtGui.QColor("blue")) self.ui.cancionTE.setFontWeight(QtGui.QFont.Bold) self.ui.cancionTE.setFontPointSize(10) self.ui.cancionTE.append(f.strip('\n')) if f[0]!='.': self.ui.cancionTE.setTextColor(QtGui.QColor("black")) self.ui.cancionTE.setFontWeight(QtGui.QFont.Bold) self.ui.cancionTE.setFontPointSize(10) self.ui.cancionTE.append(f.strip('\n')) if count>=40: if f[0]=='.': self.ui.cancionTE2.setTextColor(QtGui.QColor("blue")) self.ui.cancionTE2.setFontWeight(QtGui.QFont.Bold) self.ui.cancionTE2.setFontPointSize(10) self.ui.cancionTE2.append(f.strip('\n')) if f[0]!='.': self.ui.cancionTE2.setTextColor(QtGui.QColor("black")) self.ui.cancionTE2.setFontWeight(QtGui.QFont.Bold) self.ui.cancionTE2.setFontPointSize(10) self.ui.cancionTE2.append(f.strip('\n')) #posicionar cursor arriba cursor = QTextCursor(self.ui.cancionTE2.document()) cursor.setPosition(0) self.ui.cancionTE2.setTextCursor(cursor)
class Win(QMainWindow): def __init__(self, options): super(Win, self).__init__() self.db = dbtag.Db() self.db.open(options.db) self.db.create_tables() self.rootPath = options.filespath self._init_widgets() self._init_more() def _init_widgets(self): bigsplitter = QSplitter(Qt.Horizontal, self) self.setCentralWidget(bigsplitter) leftsplitter = QSplitter(Qt.Vertical, self) self.tabWidget = QTabWidget(self) self.tagChooser = TagChooser(self.db) self.dirChooser = QTreeView(self) self.tabWidget.addTab(self.dirChooser, 'Dir') self.tabWidget.addTab(self.tagChooser, 'Tags') self.tagEditor = TagEditor(self.db) self.imageList = ImageList() leftsplitter.addWidget(self.tabWidget) leftsplitter.addWidget(self.tagEditor) bigsplitter.addWidget(leftsplitter) bigsplitter.addWidget(self.imageList) self.viewer = ImageViewer(self.db) def _init_more(self): self.setWindowTitle('Tags4') self.dirModel = QFileSystemModel() self.dirModel.setFilter(QDir.AllDirs | QDir.Drives | QDir.Hidden | QDir.NoDotAndDotDot) qidx = self.dirModel.setRootPath(self.rootPath) self.dirChooser.setModel(self.dirModel) self.dirChooser.setRootIndex(qidx) self.dirChooser.clicked.connect(self.browseSelectedDir) self.imageList.itemSelectionChanged.connect(self._editTagsItems) self.imageList.itemDoubleClicked.connect(self._spawnViewerItem) self.imageList.setSelectionMode(QAbstractItemView.ExtendedSelection) self.tabWidget.currentChanged.connect(self._tabSelected) self.tagChooser.changed.connect(self.browseSelectedTags) def editTags(self, path): self.tagEditor.setFile(path) def editTagsItems(self, paths): self.tagEditor.setFiles(paths) def spawnViewer(self, files, currentFile): self.viewer.spawn(files, currentFile) @Slot() def _editTagsItems(self): self.editTagsItems([qitem.getPath() for qitem in self.imageList.selectedItems()]) @Slot(QListWidgetItem) def _spawnViewerItem(self, qitem): self.spawnViewer(self.imageList.getFiles(), qitem.getPath()) @Slot() def browseSelectedDir(self): path = self.dirModel.filePath(self.dirChooser.currentIndex()) if not path: return files = [os.path.join(path, f) for f in os.listdir(path)] files = filter(os.path.isfile, files) files.sort() self.imageList.setFiles(files) @Slot() def browseSelectedTags(self): self.imageList.setFiles(self.tagChooser.matchingFiles()) @Slot(int) def _tabSelected(self, idx): if idx == 0: self.browseSelectedDir() else: self.browseSelectedTags() def browsePath(self, path): self.imageList.setFiles(os.path.join(path, f) for f in os.listdir(path))
class mainForm(QMainWindow): get_template_filename = pyqtSignal(str) exit_program = pyqtSignal() camera_changed = pyqtSignal(int) def __init__(self): super().__init__() self.stream = None self.image_difference_thread = None self.template_set = False self._countour_max_tresh = 10 self._countour_min_tresh = 1 self._transparency_max = 10 self._transparency_min = 0 self._countour_gamma_max = 10 self._countour_gamma_min = 1 self._color_max = 255 self._color_min = 0 self.screen_resolution = None self.grid_layout = None self.output_picture = None self.initUI() self.init_image_difference() if self.webcam_switcher.count() > 0: self.stream = streamCapture(self.webcam_switcher.itemData(self.webcam_switcher.currentIndex())) self.stream.getframe.connect(self.mat2qimage) self.webcam_switcher.currentIndexChanged.connect(self.camera_switcher_index_changed) self.camera_changed.connect(self.stream.reopenStream) self.stream.start() self.exit_program.connect(self.stream.exit) ### отрисовка интерфейса def initUI(self): self.screen_resolution = QApplication.desktop().screenGeometry() # self.resize(self.screen_resolution.size()) # self.move(self.screen_resolution.left(), self.screen_resolution.top()) self.grid_layout = QGridLayout() self.central_widget = QWidget() self.central_widget.setLayout(self.grid_layout) self.central_widget.setMaximumSize(self.screen_resolution.width() // 4 * 3, self.screen_resolution.height() // 4 * 3) self.setCentralWidget(self.central_widget) self.camera_label = QLabel("Camera:") self.grid_layout.addWidget(self.camera_label, 0, 0, 1, 1, Qt.AlignmentFlag.AlignHCenter) self.webcam_switcher = QComboBox() self.detect_webcam_devices(self.webcam_switcher) self.grid_layout.addWidget(self.webcam_switcher, 0, 1, 1, 3) self.output_picture = QLabel() self.grid_layout.addWidget(self.output_picture, 1, 0, 1, 4) ### creating right dock self.right_dock_layout = QVBoxLayout() self.right_dock_widget = QDockWidget() self.right_dock_widget.setFeatures(QDockWidget.DockWidgetFeature.DockWidgetMovable | QDockWidget.DockWidgetFeature.DockWidgetFloatable) self.right_dock_widget.setMinimumSize(self.screen_resolution.width() // 4, self.screen_resolution.height()) right_dock = QWidget(self.right_dock_widget) right_dock.setMinimumSize(self.screen_resolution.width() // 4, self.screen_resolution.height()) right_dock.setLayout(self.right_dock_layout) template_label = QLabel("Templates") template_label.setMinimumSize(50, 25) self.right_dock_layout.addWidget(template_label) self.filter_template_edit = QLineEdit() self.filter_template_edit.setPlaceholderText("Filter (Ctr + Alt + f)") template_label.setMinimumSize(90, 25) self.filter_template_edit.setStyleSheet( "background-image: url(../image_difference/icons/searchIcon.png); background-repeat: no-repeat; background-position: right;") self.right_dock_layout.addWidget(self.filter_template_edit) self.file_system_model = QFileSystemModel() self.file_system_model.setFilter(QDir.Filter.AllDirs | QDir.Filter.NoDotAndDotDot | QDir.Filter.AllEntries) self.file_system_model.setRootPath(QDir.currentPath()) self.directory_tree_view = QTreeView() self.directory_tree_view.setModel(self.file_system_model) self.directory_tree_view.setMinimumSize(200, 100) self.directory_tree_view.hideColumn(1) self.directory_tree_view.hideColumn(2) self.directory_tree_view.hideColumn(3) # self.directory_tree_view.sortByColumn(0) self.directory_tree_view.setSortingEnabled(True) self.directory_tree_view.doubleClicked.connect(self.load_template) self.directory_tree_view.setRootIndex(self.file_system_model.index("../image_difference/")) self.right_dock_layout.addWidget(self.directory_tree_view) self.load_template_button = QPushButton("Select Template") self.load_template_button.setMaximumSize(self.screen_resolution.width() // 4 - 30, 30) self.load_template_button.clicked.connect(self.load_template) self.right_dock_layout.addWidget(self.load_template_button) self.create_template_button = QPushButton("Create Template") self.create_template_button.setMaximumSize(self.screen_resolution.width() // 4 - 30, 30) self.create_template_button.clicked.connect(self.create_template) self.right_dock_layout.addWidget(self.create_template_button) self.template_image_widget = QWidget() self.template_image_widget.setMinimumSize(self.screen_resolution.width() // 4 - 20, self.screen_resolution.width() // 4 - 10) self.template_image_back = QLabel(self.template_image_widget) self.template_image_back.resize(self.screen_resolution.width() // 4 - 20, self.screen_resolution.width() // 4 - 10) pix = QPixmap(self.template_image_back.size()) pix.fill(Qt.lightGray) rect = QRectF(0.0, 0.0, self.template_image_back.size().width(), self.template_image_back.size().height()) painter = QPainter() painter.begin(pix) painter.setRenderHints(QPainter.Antialiasing, True) path = QPainterPath() path.addRoundedRect(rect, 5.0, 5.0) painter.drawPath(path) painter.end() self.template_image_back.setPixmap(pix) self.template_image = QLabel(self.template_image_widget) self.template_image.move(5, 5) self.template_image.resize(self.screen_resolution.width() // 4 - 30, self.screen_resolution.width() // 4 - 30) self.template_image_text = QLabel(self.template_image_widget, text="Current Template") self.template_image_text.setStyleSheet("font-weight: bold") self.template_image_text.move(self.screen_resolution.width() // 8 - 65, 20) self.right_dock_layout.addWidget(self.template_image_widget) self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.right_dock_widget) ### creating bottom dock self.bottom_dock_layout = QGridLayout() self.bottom_dock_layout.setSpacing(10) self.bottom_dock_widget = QDockWidget() self.bottom_dock_widget.setMinimumSize(self.screen_resolution.width() // 4 * 3 - 10, self.screen_resolution.height() // 4 - 10) bottom_dock = QWidget(self.bottom_dock_widget) bottom_dock.setMinimumSize(self.screen_resolution.width() // 4 * 3 - 20, self.screen_resolution.height() // 4 - 20) bottom_dock.move(10, 10) bottom_dock.setLayout(self.bottom_dock_layout) settings_label = QLabel("Settings:") self.bottom_dock_layout.addWidget(settings_label, 0, 0, 1, 2, Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop) countour_tresh_label = QLabel("Countour Tresh:") self.bottom_dock_layout.addWidget(countour_tresh_label, 1, 0, 1, 1, Qt.AlignmentFlag.AlignTop) self.countour_tresh_slider = QSlider(Qt.Orientation.Horizontal) self.countour_tresh_slider.setTickPosition(QSlider.TickPosition.TicksBelow) self.countour_tresh_slider.setRange(self._countour_min_tresh, self._countour_max_tresh) self.countour_tresh_slider.setValue(2) self.bottom_dock_layout.addWidget(self.countour_tresh_slider, 1, 1, 1, 1, Qt.AlignmentFlag.AlignTop) transparency_weight_label = QLabel("Transparency:") self.bottom_dock_layout.addWidget(transparency_weight_label, 2, 0, 1, 1, Qt.AlignmentFlag.AlignTop) self.transparency_weight_slider = QSlider(Qt.Orientation.Horizontal) self.transparency_weight_slider.setTickPosition(QSlider.TickPosition.TicksBelow) self.transparency_weight_slider.setValue(6) self.transparency_weight_slider.setRange(self._transparency_min, self._transparency_max) self.bottom_dock_layout.addWidget(self.transparency_weight_slider, 2, 1, 1, 1, Qt.AlignmentFlag.AlignTop) countour_gamma_label = QLabel("Countour Gamma:") self.bottom_dock_layout.addWidget(countour_gamma_label, 3, 0, 1, 1, Qt.AlignmentFlag.AlignTop) self.countour_gamma_slider = QSlider(Qt.Orientation.Horizontal) self.countour_gamma_slider.setTickPosition(QSlider.TickPosition.TicksBelow) self.countour_gamma_slider.setValue(8) self.countour_gamma_slider.setRange(self._countour_gamma_min, self._countour_gamma_max) self.bottom_dock_layout.addWidget(self.countour_gamma_slider, 3, 1, 1, 1, Qt.AlignmentFlag.AlignTop) ### right side of settings countour_color_label = QLabel("Countour Color:") self.bottom_dock_layout.addWidget(countour_color_label, 0, 2, 1, 2, Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop) r_color_label = QLabel("R:") self.bottom_dock_layout.addWidget(r_color_label, 1, 2, 1, 1, Qt.AlignmentFlag.AlignTop) self.r_color_slider = QSlider(Qt.Orientation.Horizontal) self.r_color_slider.setTickPosition(QSlider.TickPosition.TicksBelow) self.r_color_slider.setRange(self._color_min, self._color_max) self.r_color_slider.setValue(255) self.bottom_dock_layout.addWidget(self.r_color_slider, 1, 3, 1, 1, Qt.AlignmentFlag.AlignTop) g_color_label = QLabel("G:") self.bottom_dock_layout.addWidget(g_color_label, 2, 2, 1, 1, Qt.AlignmentFlag.AlignTop) self.g_color_slider = QSlider(Qt.Orientation.Horizontal) self.g_color_slider.setTickPosition(QSlider.TickPosition.TicksBelow) self.g_color_slider.setRange(self._color_min, self._color_max) self.bottom_dock_layout.addWidget(self.g_color_slider, 2, 3, 1, 1, Qt.AlignmentFlag.AlignTop) b_color_label = QLabel("B:") self.bottom_dock_layout.addWidget(b_color_label, 3, 2, 1, 1, Qt.AlignmentFlag.AlignTop) self.b_color_slider = QSlider(Qt.Orientation.Horizontal) self.b_color_slider.setTickPosition(QSlider.TickPosition.TicksBelow) self.b_color_slider.setRange(self._color_min, self._color_max) self.bottom_dock_layout.addWidget(self.b_color_slider, 3, 3, 1, 1, Qt.AlignmentFlag.AlignTop) self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, self.bottom_dock_widget) self.setCorner(Qt.Corner.BottomRightCorner, Qt.DockWidgetArea.RightDockWidgetArea) def init_image_difference(self): self.image_difference_thread = imageDifference() self.get_template_filename.connect(self.image_difference_thread.set_template_image) self.countour_tresh_slider.valueChanged.connect(self.image_difference_thread.set_countour_tresh_value) self.transparency_weight_slider.valueChanged.connect(self.image_difference_thread.set_transparency_weight_value) self.countour_gamma_slider.valueChanged.connect(self.image_difference_thread.set_countour_gamma_value) self.r_color_slider.valueChanged.connect(self.image_difference_thread.set_countour_color_r) self.g_color_slider.valueChanged.connect(self.image_difference_thread.set_countour_color_g) self.b_color_slider.valueChanged.connect(self.image_difference_thread.set_countour_color_b) self.image_difference_thread.output_image_defference.connect(self.mat2qimage) self.image_difference_thread.set_template_picture.connect(self.set_template_picture) self.image_difference_thread.start() def detect_webcam_devices(self, combo_box): _video_capture = cv2.VideoCapture() _dev_id = 0 while (_dev_id < 3): if _video_capture.open(_dev_id): combo_box.addItem("Device #" + str(_dev_id + 1), _dev_id) _dev_id += 1 else: _dev_id += 1 _video_capture.release() def load_template(self): index = self.directory_tree_view.selectedIndexes()[0] if not QFileInfo(self.file_system_model.filePath(index)).isDir(): # print("load template, path:", self.file_system_model.filePath(index)) self.get_template_filename.emit(self.file_system_model.filePath(index)) def create_template(self): if self.stream is not None: template_to_save = self.stream.get_current_frame() cv2.imwrite("../image_difference/examples/template.jpg", template_to_save) print("create template") pyqtSlot(np.ndarray) def mat2qimage(self, image): rgbImage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) rgbImage = cv2.resize(rgbImage, (self.output_picture.size().width(), self.output_picture.size().height())) # rgbImage = imutils.resize(rgbImage, height=self.output_picture.height()) h, w, ch = rgbImage.shape bytesPerLine = ch * w result_image = QImage(rgbImage.data, w, h, bytesPerLine, QImage.Format_RGB888) self.output_picture.setPixmap(QPixmap.fromImage(result_image)) pyqtSlot(np.ndarray) def set_template_picture(self, image): rgbImage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # rgbImage = cv2.resize(rgbImage, (self.template_image.size().width(), # self.template_image.size().height())) rgbImage = imutils.resize(rgbImage, self.template_image.size().width()) h, w, ch = rgbImage.shape bytesPerLine = ch * w result_image = QImage(rgbImage.data, w, h, bytesPerLine, QImage.Format_RGB888) self.template_image.setPixmap(QPixmap.fromImage(result_image)) if not self.template_set: self.template_set = True self.stream.getframe.disconnect(self.mat2qimage) self.stream.getframe.connect(self.image_difference_thread.get_image) self.image_difference_thread.output_image_defference.connect(self.mat2qimage) def camera_switcher_index_changed(self, index): self.camera_changed.emit(self.webcam_switcher.itemData(index)) print("current index:", index) print("item data:", self.webcam_switcher.itemData(index)) def closeEvent(self, event): self.exit_program.emit() event.accept()
class clientUI_Interface(Ui_ClientUI): ''' Mediator class between the logic and the Presentation ''' def __init__(self, ftpClientUIMain, ftpClient, homeDir): Ui_ClientUI.__init__(self) self.setupUi(ftpClientUIMain) self.ftpClient = ftpClient #-----------------Local------------------------------------------------------ self.homeDir = homeDir self.localDir_treeView.setContextMenuPolicy( QtCore.Qt.CustomContextMenu) self.localDir_treeView.customContextMenuRequested.connect( self.localMenu) self.populateLocalDir() #-----------------remote---------------------------------------------------- self.remoteDir_tableWidget.setContextMenuPolicy( QtCore.Qt.CustomContextMenu) self.remoteDir_tableWidget.customContextMenuRequested.connect( self.remoteMenu) # Reset and hide progress bar self.progressBar.setValue(0) self.progressBar.hide() # Disable all remote widgets and buttons self.Back_pushButton.setEnabled(False) self.Quit_pushButton.setEnabled(False) self.btn_refreshRemoteDir.setEnabled(False) self.remoteDir_tableWidget.setEnabled(False) self.dirName_lineEdit.setEnabled(False) self.btn_createDir.setEnabled(False) self.btn_Cancell_createDir.setEnabled(False) # Initialise the table for listing files self.updateServerDirectoryList() # Create a thread pool self.threadpool = QtCore.QThreadPool() #----------------------- ACTION FUNCTIONS ------------------------------- self.connect_pushButton.clicked.connect(self.connectToServer) self.Quit_pushButton.clicked.connect(self.quit) self.btn_refreshRemoteDir.clicked.connect(self.refreshRemote) self.btn_RefreshLocalDir.clicked.connect(self.refreshLocal) self.btn_createDir.clicked.connect(self.createDir) self.btn_Cancell_createDir.clicked.connect(self.disableFolderEdit) self.Back_pushButton.clicked.connect(self.directoryReturn) self.remoteDir_tableWidget.doubleClicked.connect(self.openFolder) #================================================================================== def setSatus(self, isError, status): self.ftpClient.isError = isError self.ftpClient.server_response = status self.dispStatus() #================================================================================== def dispStatus(self): if self.ftpClient.isError: self.status_label.setStyleSheet( 'color: red; font-family:Times New Roman') else: self.status_label.setStyleSheet( 'color: blue; font-family:Times New Roman; font-size: 11pt') self.status_label.setText(str(self.ftpClient.server_response)) #================================================================================== def connectToServer(self): if not self.ftpClient.IsConnected: self.ftpClient.initializeFTPConnection( str(self.lineEdit_host.text())) self.dispStatus() self.loginToServer() if self.ftpClient.IsValidUser: self.Quit_pushButton.setEnabled(True) self.connect_pushButton.setEnabled(False) self.connect_pushButton.setText("Connect") self.Back_pushButton.setEnabled(True) self.btn_refreshRemoteDir.setEnabled(True) self.remoteDir_tableWidget.setEnabled(True) self.refreshRemote() self.conStatus.setStyleSheet( 'color: blue; font-family:Times New Roman; font-size: 11pt') self.conStatus.setText("Online : ") self.dispStatus() #================================================================================== def loginToServer(self): if self.ftpClient.IsConnected: self.connect_pushButton.setText("Login") username = str(self.lineEdit_username.text()) password = str(self.lineEdit_Password.text()) self.ftpClient.login(username, password) self.dispStatus() #================================================================================== def populateLocalDir(self): self.localModel = QFileSystemModel() self.localModel.setRootPath(QtCore.QDir.rootPath()) self.localDir_treeView.setModel(self.localModel) self.localDir_treeView.setRootIndex( self.localModel.index(str(self.homeDir))) self.localDir_treeView.setSortingEnabled(True) #================================================================================== def localMenu(self): local_menu = QtWidgets.QMenu() fileUpload = local_menu.addAction("Upload") fileUpload.triggered.connect(self.uploadFile) cursor = QtGui.QCursor() #privide a cursor location local_menu.exec_(cursor.pos()) # pass it to the menu executor #================================================================================== def uploadFile(self): if self.ftpClient.IsConnected: local_index = self.localDir_treeView.currentIndex() filename = self.localModel.fileName(local_index) filepath = self.localModel.filePath(local_index) #self.ftpClient.upload_file(filename) self.ftpClient.upLoadList.append(filename) uploadThread = actionHandler(self.ftpClient.upload_file, filename, filepath) uploadThread.signals.finished.connect(self.uploadThreadComplete) uploadThread.signals.error.connect(self.uploadFailed) uploadThread.signals.fileProgress.connect( self.displayUploadProgBar) self.threadpool.start(uploadThread) msg = "Upload file : " + filename self.setSatus(False, msg) self.dispStatus() else: self.uploadFailed() self.disconnected() #================================================================================== def uploadFailed(self): msg = "Upload Failed, Check connection" self.setSatus(True, msg) self.dispStatus() print(msg) #================================================================================== def uploadThreadComplete(self): self.setSatus(False, "Done Uploading") self.dispStatus() self.progressBar.hide() self.up_downLoadlabel.setText("") self.progressBar.setEnabled(False) self.Back_pushButton.setEnabled(True) self.btn_refreshRemoteDir.setEnabled(True) self.remoteDir_tableWidget.setEnabled(True) self.refreshRemote() #================================================================================== def displayUploadProgBar(self): #, filename) if len(self.ftpClient.upLoadList) is not 0: self.progressBar.show() self.progressBar.setEnabled(True) self.up_downLoadlabel.setText("Uploading file") self.progressBar.setValue(self.ftpClient.getProgressVal()) return #================================================================================== def remoteMenu(self): remote_menu = QtWidgets.QMenu() fileDownload = remote_menu.addAction("Download") fileDownload.triggered.connect(self.downloadFile) fileDownload = remote_menu.addAction("Open") fileDownload.triggered.connect(self.openFolder) fileDownload = remote_menu.addAction("Delete") fileDownload.triggered.connect(self.deleteFile) fileDownload = remote_menu.addAction("New Folder") fileDownload.triggered.connect(self.enableFolderEdit) cursor = QtGui.QCursor() remote_menu.exec_(cursor.pos()) #================================================================================== def deleteFile(self): for currentQTableWidgetRow in self.remoteDir_tableWidget.selectionModel( ).selectedRows(): if currentQTableWidgetRow.row() != 0: try: filename = self.remoteDir_tableWidget.item( currentQTableWidgetRow.row(), 0).text() permission = self.remoteDir_tableWidget.item( currentQTableWidgetRow.row(), 3).text() if permission.find('d') is not -1: path = self.addPath(filename) self.ftpClient.directory_delete(path) self.dispStatus() self.refreshRemote() else: path = self.addPath(filename) self.ftpClient.file_delete(path) self.dispStatus() self.refreshRemote() except: self.setSatus(True, "Cant delete File") self.dispStatus() return #================================================================================== def enableFolderEdit(self): self.dirName_lineEdit.setEnabled(True) self.btn_createDir.setEnabled(True) self.label_foldername.setEnabled(True) self.btn_Cancell_createDir.setEnabled(True) self.Back_pushButton.setEnabled(False) self.btn_refreshRemoteDir.setEnabled(False) self.remoteDir_tableWidget.setEnabled(False) #================================================================================== def disableFolderEdit(self): self.btn_Cancell_createDir.setEnabled(False) self.dirName_lineEdit.setEnabled(False) self.label_foldername.setEnabled(False) self.btn_createDir.setEnabled(False) self.Back_pushButton.setEnabled(True) self.btn_refreshRemoteDir.setEnabled(True) self.remoteDir_tableWidget.setEnabled(True) #================================================================================== def createDir(self): self.dirName_lineEdit.setFocus() directoryName = str(self.dirName_lineEdit.text()) self.dirName_lineEdit.clear() self.ftpClient.directory_create(directoryName) self.disableFolderEdit() self.dispStatus() self.refreshRemote() return #================================================================================== def addPath(self, filename): self.ftpClient.directory_print() print(self.ftpClient.serverDir) self.ftpClient.serverDir = self.ftpClient.serverDir.replace('\r\n', '') s = '\\' path = self.ftpClient.serverDir + s + filename path = [self.ftpClient.serverDir, str(filename)] path = '\\'.join(path) return path #================================================================================== def openFolder(self): for currentQTableWidgetRow in self.remoteDir_tableWidget.selectionModel( ).selectedRows(): try: filename = self.remoteDir_tableWidget.item( currentQTableWidgetRow.row(), 0).text() except: return if (filename == ".."): self.directoryReturn() elif not (filename == ".."): try: permission = self.remoteDir_tableWidget.item( currentQTableWidgetRow.row(), 3).text() if permission.find('d') is not -1: path = self.addPath(filename) print('path :', path) self.ftpClient.directory_change(path) self.dispStatus() self.refreshRemote() else: self.setSatus(True, "Cant open file, Download instead") self.dispStatus() except: self.setSatus(True, "Cant open file, Download instead") self.dispStatus() else: self.updateCurrentDir() self.ftpClient.directory_print() self.dispStatus() self.refreshRemote() #================================================================================== def directoryReturn(self): self.ftpClient.directory_return() self.ftpClient.directory_print() self.dispStatus() self.refreshRemote() #================================================================================== def downloadFile(self): for currentQTableWidgetRow in self.remoteDir_tableWidget.selectionModel( ).selectedRows(): try: filename = self.remoteDir_tableWidget.item( currentQTableWidgetRow.row(), 0).text() except: return permission = self.remoteDir_tableWidget.item( currentQTableWidgetRow.row(), 3).text() if permission.find('d') is -1: try: #saveFileInDirectory = str(QtWidgets.QFileDialog.getExistingDirectory(None, "Save File In Directory", currentDirectory,\ #QtWidgets.QFileDialog.ShowDirsOnly)) self.ftpClient.downloadList.append(filename) self.callDownloadFn() downloadThread = actionHandler( self.ftpClient.download_file, filename) downloadThread.signals.finished.connect( self.downloadThreadComplete) downloadThread.signals.error.connect(self.downloadFailed) downloadThread.signals.fileProgress.connect( self.displayDownloadProgBar) self.threadpool.start(downloadThread) except: print("Error creating download Thread") else: self.setSatus(True, "Cant downloadFile, Try open instead") self.dispStatus() self.dispStatus() #================================================================================== def callDownloadFn(self): self.setSatus(False, "Downloading ...") self.dispStatus() self.Back_pushButton.setEnabled(False) self.btn_refreshRemoteDir.setEnabled(False) self.remoteDir_tableWidget.setEnabled(False) #================================================================================== def downloadFailed(self): msg = "Download Failed!!" self.setSatus(True, msg) self.dispStatus() print(msg) #================================================================================== def downloadThreadComplete(self): self.setSatus(False, "Done Downloading") self.dispStatus() self.refreshRemote() self.progressBar.hide() self.up_downLoadlabel.setText("") self.progressBar.setEnabled(False) self.Back_pushButton.setEnabled(True) self.btn_refreshRemoteDir.setEnabled(True) self.remoteDir_tableWidget.setEnabled(True) #================================================================================== def displayDownloadProgBar(self): #, filename) if len(self.ftpClient.downloadList) is not 0: self.progressBar.show() self.progressBar.setEnabled(True) self.up_downLoadlabel.setText("Downloading file") self.progressBar.setValue(self.ftpClient.getProgressVal()) return #================================================================================== def updateCurrentDir(self): self.ftpClient.directory_print() self.remoteDir_lineEdit.setText(str(self.ftpClient.serverDir)) #================================================================================== def updateServerDirectoryList(self): try: self.remoteDir_tableWidget.setRowCount(0) # set column count self.remoteDir_tableWidget.setColumnCount(4) # Set Row Count: self.remoteDir_tableWidget.setRowCount( len(self.ftpClient.ListInDir) + 1) # Default: header = self.remoteDir_tableWidget.horizontalHeader() header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch) header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) row = 0 col = 0 for item in self.ftpClient.ListInDir: print(item) for fileProperty in item: fileTypeIco = None if col == 0: if item[3].find('x') is -1: tempFilename = fileProperty.lower() if tempFilename.endswith( ('.png', '.jpg', '.jpeg', '.bmp', '.tiff')): fileTypeIco = "assets/image.ico" elif tempFilename.endswith( ('.mp4', '.wmv', '.mkv', '.avi')): fileTypeIco = "assets/video.ico" else: fileTypeIco = "assets/file.ico" else: fileTypeIco = "assets/folder.ico" tempItem = QtWidgets.QTableWidgetItem( QtGui.QIcon(QtGui.QPixmap(fileTypeIco)), fileProperty) self.remoteDir_tableWidget.setItem(row, col, tempItem) col = col + 1 row = row + 1 col = 0 self.remoteDir_tableWidget.setHorizontalHeaderItem( 0, QtWidgets.QTableWidgetItem("Name")) self.remoteDir_tableWidget.setHorizontalHeaderItem( 1, QtWidgets.QTableWidgetItem("Size")) self.remoteDir_tableWidget.setHorizontalHeaderItem( 2, QtWidgets.QTableWidgetItem("Last Modified")) self.remoteDir_tableWidget.setHorizontalHeaderItem( 3, QtWidgets.QTableWidgetItem("Permissions")) self.remoteDir_tableWidget.setSelectionBehavior( QtWidgets.QTableView.SelectRows) except: self.setSatus(True, "Unable to update Server Directory.") self.dispStatus() #================================================================================== def refreshRemote(self): if self.ftpClient.IsConnected: self.ftpClient.getDirList() self.updateServerDirectoryList() self.updateCurrentDir() #self.setSatus(False,"Remote Directory refreshed") self.dispStatus() else: self.disconnected() #================================================================================== def refreshLocal(self): self.populateLocalDir() #================================================================================== def updateStatus(self): time.sleep(1) if self.ftpClient.IsConnected: self.status_label.setStyleSheet( 'color: blue; font-family:Times New Roman; font-size: 11pt') self.status_label.setText("...") else: self.disconnected() #================================================================================== def disconnected(self): if not self.ftpClient.IsConnected: self.Quit_pushButton.setEnabled(False) self.btn_refreshRemoteDir.setEnabled(False) self.remoteDir_lineEdit.setText("") self.remoteDir_tableWidget.clear() self.remoteDir_tableWidget.setEnabled(False) self.connect_pushButton.setEnabled(True) time.sleep(1) self.conStatus.setStyleSheet( 'color: red; font-family:Times New Roman; font-size: 11pt') self.conStatus.setText("Offline :") self.status_label.setText('') self.Back_pushButton.setEnabled(False) def quit(self): if self.ftpClient.IsConnected: self.ftpClient.logout() self.Quit_pushButton.setEnabled(False) self.btn_refreshRemoteDir.setEnabled(False) self.remoteDir_lineEdit.setText("") self.remoteDir_tableWidget.clear() self.remoteDir_tableWidget.setEnabled(False) self.connect_pushButton.setEnabled(True) self.conStatus.setStyleSheet( 'color: red; font-family:Times New Roman; font-size: 11pt') self.conStatus.setText("Offline :") self.status_label.setText('') self.Back_pushButton.setEnabled(False)
class SidebarView: def __init__(self, root, wads, controller): self.wads = wads self.current_wad = None self.wad_dir_model = QFileSystemModel() self.wad_dir = root.findChild(QTreeView, 'sidebar_waddir') self.wad_dir.setModel(self.wad_dir_model) for i in range(1, self.wad_dir.header().length()): self.wad_dir.hideColumn(i) self.wad_dir.setContextMenuPolicy(Qt.CustomContextMenu) self.wad_dir.customContextMenuRequested.connect(self.open_dir_menu) self.loadorder_model = QStandardItemModel() # rowsRemoved is called when something is moved, AFTER the model actually is updated self.loadorder_model.rowsRemoved.connect( self.update_load_ordered_files) self.loadorder = root.findChild(QListView, 'sidebar_loadorder') self.loadorder.setModel(self.loadorder_model) self.loadorder.clicked.connect(self.update_load_ordered_files) self.loadorder.setContextMenuPolicy(Qt.CustomContextMenu) self.loadorder.customContextMenuRequested.connect( self.open_load_order_menu) self.search_button = root.findChild(QPushButton, 'sidebar_idgames_search') def search(): display_widget(root, WidgetIndices.IDGAMES_SEARCH) self.search_button.clicked.connect(search) self.random_button = root.findChild(QPushButton, 'sidebar_idgames_random') self.random_button.clicked.connect(controller.random_clicked) self.selected_wad_id = None self.iwad_only_checkbox = root.findChild(QCheckBox, 'sidebar_iwad_only') # checking this should send an empty file_paths list to wads.model. self.iwad_only_checkbox.stateChanged.connect( self.update_load_ordered_files) def show_dir(self, wad): self.current_wad = wad self.wad_dir_model.setRootPath(QDir.currentPath()) self.wad_dir.setRootIndex(self.wad_dir_model.index(wad.path)) self.selected_path = wad.path self.selected_wad_id = wad.id try: self.loadorder_model.clear() for file_path in wad.file_paths: file_name = os.path.basename(file_path) item = QStandardItem(file_name) item.setData(file_path, PATH_ROLE) item.setFlags(LOAD_ORDER_ITEM_FLAGS) item.setCheckable(True) item.setCheckState(Qt.Checked) self.loadorder_model.appendRow(item) except KeyError: print('file paths not found in:', wad.name) def update_load_ordered_files(self, *_): file_paths_reordered = [] for i in range(self.loadorder_model.rowCount()): item = self.loadorder_model.item(i) if self.iwad_only_checkbox.checkState() != Qt.Checked: item.setEnabled(True) if item.checkState() == Qt.Checked: file_paths_reordered.append(item.data(PATH_ROLE)) else: item.setEnabled(False) self.wads.set_load_order(file_paths_reordered) def open_dir_menu(self, pos): index = self.wad_dir.indexAt(pos) file_name = self.wad_dir_model.fileName(index) file_path = self.wad_dir_model.filePath(index) add_file_to_load_order_string = 'Add {} to load order list'.format( file_name) def add_file_to_load_order(): self.current_wad.add_file_path_to_paths(file_path) self.show_dir(self.current_wad) menu_actions = [(add_file_to_load_order_string, add_file_to_load_order) ] execute_menu = make_context_menu(self.wad_dir, menu_actions) execute_menu(pos) def open_load_order_menu(self, pos): index = self.loadorder.indexAt(pos) item = self.loadorder_model.itemFromIndex(index) file_name = item.text() file_path = item.data() remove_file_from_load_order_string = 'Remove {} from load order list'.format( file_name) def remove_file_from_load_order(): self.current_wad.remove_file_path_from_paths(file_path) self.show_dir(self.current_wad) menu_actions = [(remove_file_from_load_order_string, remove_file_from_load_order)] execute_menu = make_context_menu(self.loadorder, menu_actions) execute_menu(pos)
class FileRenamer(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent=parent) self.help_text = '' self.in_context = False self.build_ui() self.connect_events() self.cache = {} def build_ui(self): self.ui = UI_file_renamer.Ui_Form() self.ui.setupUi(self) self.setAcceptDrops(True) self.original_model = QFileSystemModel() self.original_model.setNameFilters(["*.wav", "*.zc"]) self.original_model.setNameFilterDisables(False) self.ui.treeview_original.setModel(self.original_model) for i in range(6, 0, -1): self.ui.treeview_original.setColumnHidden(i, True) self.changed_model = RenamedFileSystemModel( rename_function=self.change_fname_function) self.changed_model.setNameFilters(["*.wav", "*.zc"]) self.changed_model.setNameFilterDisables(False) self.ui.treeview_changed.setModel(self.changed_model) for i in range(6, 0, -1): self.ui.treeview_changed.setColumnHidden(i, True) icon = QIcon( utils.resource_path('../resources/icons/nabat_circle_color.ico')) self.setWindowIcon(icon) self.ui.progressBar.setVisible(False) self.ui.progressBar_tarball.setVisible(False) def connect_events(self): self.ui.btn_browse.clicked.connect(self.browse) self.ui.btn_browse_output.clicked.connect(self.browse_output) self.ui.directory_name.textChanged.connect(self.load_directory) self.ui.btn_save.clicked.connect(self.save) self.ui.btn_tarball.clicked.connect(self.tarball) self.ui.treeview_original.expanded.connect(self.expand_changed) self.ui.treeview_original.collapsed.connect(self.collapse_changed) self.ui.treeview_changed.expanded.connect(self.expand_original) self.ui.treeview_changed.collapsed.connect(self.collapse_original) self.sb_original = self.ui.treeview_original.verticalScrollBar() self.sb_original.valueChanged.connect(self.sync_scroll_right) self.sb_changed = self.ui.treeview_changed.verticalScrollBar() self.sb_changed.valueChanged.connect(self.sync_scroll_left) self.ui.chk_auto_rename.stateChanged.connect(self.update_filenames) self.ui.chk_replace.stateChanged.connect(self.update_filenames) self.ui.replace_from.textChanged.connect(self.update_filenames) self.ui.replace_to.textChanged.connect(self.update_filenames) self.ui.chk_replace.stateChanged.connect(self.enable_chk_replace) self.ui.chk_replace2.stateChanged.connect(self.enable_chk_replace2) self.ui.chk_folderGRTS.stateChanged.connect(self.enable_chk_grtsfolder) self.ui.chk_sitename_folder.stateChanged.connect( self.enable_chk_sitefolder) self.ui.site_text.textChanged.connect(self.update_filenames) self.ui.grts_txt.textChanged.connect(self.update_filenames) self.ui.replace_from.textChanged.connect(self.update_filenames) self.ui.replace_to.textChanged.connect(self.update_filenames) self.ui.replace_from2.textChanged.connect(self.update_filenames) self.ui.replace_to2.textChanged.connect(self.update_filenames) self.ui.grts_folder.toggled.connect(self.grts_parent_change) self.ui.grts_folder2x.toggled.connect(self.grts_parent_change) self.ui.site_folder.toggled.connect(self.site_parent_change) self.ui.site_folder2x.toggled.connect(self.site_parent_change) def grts_parent_change(self): self.ui.grts_txt.setText('') self.update_filenames() def site_parent_change(self): self.ui.site_text.setText('') self.update_filenames() def enable_chk_replace(self): checked = self.ui.chk_replace.isChecked() self.ui.replace_from.setEnabled(checked) self.ui.replace_to.setEnabled(checked) self.ui.chk_use_re.setEnabled(checked) self.ui.label_2.setEnabled(checked) self.update_filenames() def enable_chk_replace2(self): checked = self.ui.chk_replace2.isChecked() self.ui.replace_from2.setEnabled(checked) self.ui.replace_to2.setEnabled(checked) self.ui.chk_use_re2.setEnabled(checked) self.ui.label_3.setEnabled(checked) self.update_filenames() def enable_chk_grtsfolder(self): checked = self.ui.chk_folderGRTS.isChecked() self.ui.grts_folder.setEnabled(checked) self.ui.grts_folder2x.setEnabled(checked) self.ui.grts_folder3x.setEnabled(checked) self.ui.grts_txt.setEnabled(checked) self.update_filenames() def enable_chk_sitefolder(self): checked = self.ui.chk_sitename_folder.isChecked() self.ui.site_folder.setEnabled(checked) self.ui.site_folder2x.setEnabled(checked) self.ui.site_folder3x.setEnabled(checked) self.ui.site_text.setEnabled(checked) self.update_filenames() def sync_scroll_right(self, int): self.sb_changed.setValue(self.sb_original.value()) def sync_scroll_left(self, int): self.sb_original.setValue(self.sb_changed.value()) def update_filenames(self): self.load_directory() def expand_changed(self, index): self.ui.treeview_changed.setExpanded( self.changed_model.index(self.original_model.filePath(index)), True) def collapse_changed(self, index): self.ui.treeview_changed.setExpanded( self.changed_model.index(self.original_model.filePath(index)), False) def expand_original(self, index): self.ui.treeview_original.setExpanded( self.original_model.index(self.changed_model.filePath(index)), True) def collapse_original(self, index): self.ui.treeview_original.setExpanded( self.original_model.index(self.changed_model.filePath(index)), False) def browse(self): settings = QSettings('USGS', 'guanoeditor') last_data_fname = str(Path(settings.value('lastDataDname', '')).parent) dname = QFileDialog.getExistingDirectory(self, "Open a folder", last_data_fname) if dname: settings.setValue('lastDataDname', dname) self.ui.directory_name.setText(dname) self.load_directory() def browse_output(self): settings = QSettings('USGS', 'guanoeditor') last_data_fname = str(Path(settings.value('lastDataDname', '')).parent) dname = QFileDialog.getExistingDirectory(self, "Select an output folder", last_data_fname) if dname: settings.setValue('lastDataDname', dname) self.ui.directory_name_output.setText(dname) def dragEnterEvent(self, e): if e.mimeData().hasUrls() and e.mimeData().urls()[0].isLocalFile(): url = e.mimeData().urls()[0].toLocalFile() if url.endswith('.wav'): e.accept() else: e.ignore() else: e.ignore() def dropEvent(self, e): """ Updates the form with the contents of an xml node dropped onto it. Parameters ---------- e : qt event Returns ------- None """ try: e.setDropAction(Qt.CopyAction) e.accept() url = e.mimeData().urls()[0].toLocalFile() self.ui.file_name.setText(url) # self.from_xml(element) except: e = sys.exc_info()[0] print('problem drop', e) def change_fname_function(self, fname, index=None, f=None): renamed = fname if self.ui.chk_auto_rename.isChecked(): try: renamed = utils.clean_name(fname) except: renamed = fname try: if self.ui.chk_replace.isChecked(): if self.ui.chk_use_re.isChecked(): renamed = re.sub(self.ui.replace_from.text(), self.ui.replace_to.text(), renamed) else: renamed = renamed.replace(self.ui.replace_from.text(), self.ui.replace_to.text()) except: pass try: if self.ui.chk_replace2.isChecked(): if self.ui.chk_use_re2.isChecked(): renamed = re.sub(self.ui.replace_from2.text(), self.ui.replace_to2.text(), renamed) else: renamed = renamed.replace(self.ui.replace_from2.text(), self.ui.replace_to2.text()) except: pass if not self.ui.chk_folderGRTS.isChecked() and \ not self.ui.chk_sitename_folder.isChecked(): return renamed try: parts = renamed.split('_') time_str = parts[-1] date_str = parts[-2] if len(parts) == 4: grts_str, site_str = parts[:2] elif len(parts) == 3: grts_str = parts[0] site_str = 'UnknownSiteName' except: return renamed if self.ui.chk_folderGRTS.isChecked(): grts_str = self.ui.grts_txt.text() if not grts_str: if self.ui.grts_folder.isChecked(): if index is not None: grts_str = self.changed_model.parent(index).data() elif f is not None: grts_str = f.parent() elif self.ui.grts_folder2x.isChecked(): if index is not None: grts_str = self.changed_model.parent( index).parent().data() elif f is not None: grts_str = f.parent().parent() elif self.ui.grts_folder3x.isChecked(): if index is not None: grts_str = self.changed_model.parent( index).parent().parent().data() elif f is not None: grts_str = f.parent().parent().parent() if self.ui.chk_sitename_folder.isChecked(): site_str = self.ui.site_text.text() if not site_str: if self.ui.site_folder.isChecked(): if index is not None: site_str = self.changed_model.parent(index).data() elif f is not None: site_str = f.parent() elif self.ui.site_folder2x.isChecked(): if index is not None: site_str = self.changed_model.parent( index).parent().data() elif f is not None: site_str = f.parent().parent() elif self.ui.site_folder3x.isChecked(): if index is not None: site_str = self.changed_model.parent( index).parent().parent().data() elif f is not None: site_str = f.parent().parent().parent() try: parts = [grts_str, site_str, date_str, time_str] renamed = "_".join(parts) except: return renamed return renamed def load_directory(self): self.ui.treeview_original.setRootIndex( self.original_model.index(self.ui.directory_name.text())) self.original_model.setRootPath(self.ui.directory_name.text()) self.ui.treeview_changed.setRootIndex( self.changed_model.index(self.ui.directory_name.text())) self.changed_model.setRootPath(self.ui.directory_name.text()) def save(self): d = Path(self.ui.directory_name.text()) wavs = list(d.glob('**\*.wav')) wavs += list(d.glob('**\*.zc')) self.ui.progressBar.setVisible(True) self.ui.progressBar.setMinimum(1) self.ui.progressBar.setMaximum(len(wavs)) self.ui.progressBar.setVisible(1) if self.ui.directory_name_output.text(): if not Path(self.ui.directory_name_output.text()).exists(): msq = r"The output directory specified does not exist! Please point to an existing directory." QMessageBox.warning(self, "Output directory does not exist", msg) return None out_dir = Path(self.ui.directory_name_output.text()) make_copy = True else: out_dir = Path(self.ui.directory_name.text()) make_copy = False for f in wavs: original_fname = f.name new_fname = self.change_fname_function(original_fname, f=f) full_name = f.parent.joinpath(new_fname) full_name = str(full_name).replace(str(Path(self.ui.directory_name.text())), \ str(out_dir)) if not Path(full_name).exists(): Path(full_name).parent.mkdir(parents=True, exist_ok=True) if make_copy: shutil.copy(str(f), full_name) else: f.rename(full_name) if original_fname != new_fname: try: g = GuanoFile(full_name) g['Original Filename'] = original_fname g.write(make_backup=False) except: pass self.ui.progressBar.setValue(self.ui.progressBar.value() + 1) msg = f"Finished renaming files in directory:\n\n{out_dir}" QMessageBox.information(self, "Renaming Process Complete", msg) self.ui.progressBar.setVisible(False) def tarball(self): if self.ui.directory_name_output.text(): if not Path(self.ui.directory_name_output.text()).exists(): msq = r"The output directory specified does not exist! Please point to an existing directory." QMessageBox.warning(self, "Output directory does not exist", msg) return None out_dir = Path(self.ui.directory_name_output.text()) else: out_dir = Path(self.ui.directory_name.text()) wavs = list(out_dir.glob('**\*.wav')) wavs += list(out_dir.glob('**\*.zc')) self.ui.progressBar_tarball.setVisible(True) self.ui.progressBar_tarball.setMinimum(1) self.ui.progressBar_tarball.setMaximum(len(wavs)) self.ui.progressBar_tarball.setVisible(1) tar_name = out_dir.joinpath(out_dir.name + '.tar.gz') with tarfile.open(tar_name, "w:gz") as tar_handle: for f in wavs: tar_handle.add(str(f), arcname=f.name) self.ui.progressBar_tarball.setValue( self.ui.progressBar.value() + 1) self.ui.progressBar_tarball.setValue( self.ui.progressBar_tarball.maximum()) msg = f"Finished creating tar.gz archive of directory contents.:\n\n{tar_name}" QMessageBox.information(self, "Tarball Process Complete", msg) self.ui.progressBar_tarball.setVisible(False)
class TabTest(QWidget, form_class): def __init__(self, status_bar): super().__init__() self.setupUi(self) self.status_bar = status_bar self.model = None self.set_tree_view() self.check_model_loaded() self.set_events() def set_tree_view(self): self.root_path = "../../" self.file_model = QFileSystemModel() self.file_model.setRootPath(self.root_path) self.tree_view.setModel(self.file_model) self.tree_view.setRootIndex(self.file_model.index(self.root_path)) self.tree_view.setColumnHidden(1, True) self.tree_view.setColumnHidden(2, True) self.tree_view.setColumnHidden(3, True) def check_model_loaded(self): if self.model is None: self.label_state.setText('Not loaded') else: self.label_state.setText('Loaded') def set_events(self): self.button_load.clicked.connect(self.on_click_load) self.tree_view.clicked.connect(self.on_click_tree_view) def on_click_load(self): self.status_bar.showMessage('Load model...') path = QFileDialog.getOpenFileName(self, 'Select model', '', 'Pytorch model (*.pt)')[0] if path: self.model = torch.load(path) self.device = torch.device( "cuda:0" if torch.cuda.is_available() else "cpu") self.model.eval() self.model = self.model.to(self.device) self.check_model_loaded() self.status_bar.clearMessage() def on_click_tree_view(self, index): if not self.file_model.isDir(index): path = self.file_model.filePath(index) image = cv2.imread(path) resized = cv2.resize( image, (self.label_image.width(), self.label_image.height()), interpolation=cv2.INTER_AREA) self.set_image(resized, self.label_image) if self.model is not None: gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) data = torch.from_numpy(gray).float() / 255.0 data = torch.unsqueeze(torch.unsqueeze(data, 0), 0) data = data.to(self.device) with torch.no_grad(): output = self.model(data) _, pred = torch.max(output.data, 1) pred_number = pred.cpu().numpy()[0] self.label_result.setText(str(pred_number)) def set_image(self, frame, label): image = QtGui.QImage(frame, frame.shape[1], frame.shape[0], frame.shape[1] * 3, QtGui.QImage.Format_BGR888) pixmap = QtGui.QPixmap(image) label.setPixmap(pixmap)
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent=parent) # 初始化工作目录 self.workdir = os.getcwd() + os.sep + get_default_workdir() # 初始化UI self._initUI() # 初始化文件管理器 self.model = QFileSystemModel() # 初始化两个数组,用于向鼠标追踪方法传递数据 self.axis_y_data_arr = [] self.axis_x_dict_arr = [] # 判断程序所在目录下data文件夹是否存在 if os.path.isdir(self.workdir): # 存在,设置路径提示文本框 self.lineEdit.setText(self.workdir) # 设置工作目录 self.changeworkdir(self.workdir) else: # 首次启动,默认工作目录未找到,询问用户是否设置工作目录 self.set_work_dir(True) # 状态栏提示欢迎语 self.statusbar.showMessage("RSA:Welcome to Rock-Spectrum-Assistant") # 唤醒窗口,把窗口提到最前方 self.raise_() def _initUI(self): # 载入UI.py self.setupUi(self) # 关联菜单栏到方法 self.aboutwin = aboutDialog() self.Help.triggered.connect(self.helpmanual) self.helpwin = helpdialog() self.About.triggered.connect(self.aboutthisprogram) self.notepad = Notepad(self.workdir) self.Notepad.triggered.connect(lambda: self.addfile(True)) self.findpeaksdialog = findpeaksdialog() self.Findpeaks.triggered.connect(self.findpeakswin) # 把子窗体plot、clear按钮点击交给RSA主窗体处理 self.findpeaksdialog.findpeaksbutton.clicked.connect( self.findpeaksplot) self.findpeaksdialog.clearbutton.clicked.connect(self.clearfindpeaks) self.searchdialog = searchdialog(self.workdir) # 把搜索子窗体双击事件连接到RSA主窗体进行处理 self.searchdialog.listWidget.itemDoubleClicked.connect( self.searchdialogitemdoubleclicked) # checkbox相关设置 self.crosshaircheckbox.stateChanged.connect( lambda: self.crosshaircheckboxstateChanged(self.crosshaircheckbox)) self.showgridcheckbox.stateChanged.connect( lambda: self.showgridcheckboxstateChanged(self.showgridcheckbox)) # treeView右键菜单关联 self.treeView.setContextMenuPolicy(Qt.CustomContextMenu) self.treeView.customContextMenuRequested.connect(self.context_menu) # 绘图板鼠标追踪鼠标跟踪 self.pyqtgraph.setMouseTracking(True) self.pyqtgraph.scene().sigMouseMoved.connect(self.mouseMoved) # 获取绘图板绘图对象 self.plotItem = self.pyqtgraph.getPlotItem() # 设置x、y坐标轴文字 self.plotItem.setLabel(axis='bottom', text=get_x_axis_lable()) self.plotItem.setLabel(axis='left', text=get_y_axis_lable()) def changeworkdir(self, path, isdialogflag=False): # 设置treeview工作目录,代码顺序不能颠倒 self.model.setRootPath(path) self.treeView.setModel(self.model) self.treeView.setRootIndex(self.model.index(path)) # 重设工作目录 self.workdir = self.model.rootPath() # 更换目录做一次清空,仅限不是由子窗口调用的时候 if not isdialogflag: self.on_clearbutton_clicked() def context_menu(self): # 设定鼠标点击位置的指针 index = self.treeView.currentIndex() self.mouseindex = self.model.filePath(index) # 添加右键菜单 menu = QMenu() plotfile = menu.addAction("plot") plotfile.triggered.connect(self.plotfile) addfile = menu.addAction("add") addfile.triggered.connect(self.addfile) editfile = menu.addAction("edit") editfile.triggered.connect(self.editfile) removefile = menu.addAction("remove") removefile.triggered.connect(self.removefile) opendirectory = menu.addAction("open directory") opendirectory.triggered.connect(self.opendirectory) cursor = QCursor() menu.exec_(cursor.pos()) def plotfile(self): # 绘图板上图形过多,提示用户 if self.plotcount == get_plot_limit(): QMessageBox.information( self, "温馨提示", "绘图板上已经超过" + str(get_plot_limit()) + "个图形,过多绘图会导致无法分辨,请清除绘图板", QMessageBox.Close, QMessageBox.Close) # 判断是文件指针指向的是一个目录还是文件 if os.path.isdir(self.mouseindex) or self.mouseindex == "": # 指向一个目录,提示用户 QMessageBox.information(self, "温馨提示", "选择的是一个目录,请选择一个数据文件", QMessageBox.Close, QMessageBox.Close) # 指向一个文件,尝试读取数据 elif os.path.isfile(self.mouseindex): try: self.plot(self.mouseindex) # 捕获异常 except Exception as e: QMessageBox.information(self, "警告", "文件打开失败\n请检查数据格式\n{}".format(e), QMessageBox.Close, QMessageBox.Close) self.statusbar.showMessage( "RSA:please check the data file format") def plot(self, file): # 选取画笔颜色,防止溢出 colorindex = self.plotcount if self.plotcount > len(color) - 1: colorindex = self.plotcount % len(color) # 载入数据,如果数据格式有变化这里会报错 data = load_data(file) filepath, fullfilename = os.path.split(file) filename, extension = os.path.splitext(fullfilename) # 记录数据给findpeaks使用 self.lastplotdata = data # 获取用来设置x轴坐标轴文字的数据 x_dict = self.get_axix_x_data(data) # 将数据保存到数组用于鼠标追踪调用 self.axis_y_data_arr.append(data) self.axis_x_dict_arr.append(x_dict) self.pyqtgraph.plot(x=list(x_dict.keys()), y=data.iloc[:, 0].values, pen=color[colorindex], name=filename, antialias=True) # 用绘图板上的数据数组长度来给绘图计数器赋值 DataItem_list = self.plotItem.listDataItems() self.plotcount = len(DataItem_list) # 根据UI文件默认配置,添加十字丝和网格 self.crosshaircheckboxstateChanged(self.crosshaircheckbox) self.showgridcheckboxstateChanged(self.showgridcheckbox) # 添加图例,仅第二次绘图运行 if self.plotcount == 2 and self.plotItem.legend is None: self.plotItem.addLegend() for item in DataItem_list: self.plotItem.legend.addItem(item=item, name=item.name()) # 在状态栏上显示当前绘图的文件和绘图总数 self.statusbar.showMessage("RSA:plot /" + file.lstrip(self.workdir) + " ,当前绘图总数 " + str(self.plotcount)) # TODO:恢复默认坐标值不生效 def get_axix_x_data(self, data=None): stringaxis = self.plotItem.getAxis(name='bottom') # 如果没有数据传入,坐标值设为默认值 if data is None: stringaxis.setTickSpacing() else: # 将数据表索引(波长)转换为绘图时的坐标轴数据 x_dict = dict(enumerate(data.index)) axis_x_data = [ (i, list(data.index)[i]) for i in range(0, len(data.index), get_ticks_spacing()) ] stringaxis.setTicks([axis_x_data, x_dict.items()]) return x_dict # 打开记事本与新建文件都是进行同一个操作,合并两个方法 def addfile(self, flag=False): if flag is True: self.statusbar.showMessage("RSA:start notepad") else: self.statusbar.showMessage("RSA:add file") self.notepad.newFile(get_testdata()) self.notepad.show() def editfile(self): if os.path.isdir(self.mouseindex): # 打开的是一个目录而不是一个文件时提示用户 QMessageBox.information(self, "温馨提示", "选择的是一个目录,请选择一个数据文件", QMessageBox.Close, QMessageBox.Close) elif os.path.isfile(self.mouseindex): # 分割文件拓展名,并与默认数据文件拓展名作比较 file_extension = os.path.splitext(self.mouseindex)[1] if file_extension == get_default_data_file_extension(): self.edit(self.mouseindex) else: QMessageBox.information(self, "温馨提示", "文件拓展名与数据库默认拓展名不相符", QMessageBox.Close, QMessageBox.Close) def edit(self, file): self.statusbar.showMessage("RSA:edit /" + file.lstrip(self.workdir)) self.notepad.openFileEvent(file) self.notepad.show() def removefile(self): if os.path.isdir(self.mouseindex): QMessageBox.question(self, "温馨提示", "您所选择的是一个文件夹\n出于数据安全考虑\n本程序不提供删除文件夹功能", QMessageBox.Close, QMessageBox.Close) elif os.path.isfile(self.mouseindex): filepath, filename = os.path.split(self.mouseindex) reply = QMessageBox.warning(self, "温馨提示", "是否确定删除文件" + filename, QMessageBox.Yes | QMessageBox.Cancel, QMessageBox.Cancel) if reply == QMessageBox.Yes: # 用户点击Yes,删除文件 os.remove(self.mouseindex) self.statusbar.showMessage( "RSA:remove /" + self.mouseindex.lstrip(self.workdir)) if reply == QMessageBox.Cancel: pass def opendirectory(self): # 防止用户点到空白目录无响应 if self.mouseindex == "": path = self.workdir else: path = self.mouseindex # 判断指针点击的是文件还是目录并打开 if os.path.isfile(path): path = os.path.dirname(path) self.statusbar.showMessage("RSA:open directory /" + path.lstrip(self.workdir)) os.startfile(path) @pyqtSlot() def on_clearbutton_clicked(self): self.plotItem.getAxis('bottom').setTicks(ticks=None) self.plotItem.getAxis('right').setTicks(ticks=None) # 清空图例栏的内容 if self.plotItem.legend is not None: DataItems_list = self.plotItem.listDataItems() for item in DataItems_list: self.plotItem.legend.removeItem(name=item.name()) if self.findpeaksdialog.isVisible() is True: self.clearfindpeaks() self.findpeaksdialog.close() self.axis_y_data_arr.clear() self.axis_x_dict_arr.clear() self.pyqtgraph.clear() self.plotcount = len(self.axis_y_data_arr) self.statusbar.showMessage("RSA:reset plot board") @pyqtSlot() def on_browsebutton_clicked(self, path=None, isdialogflag=False): if path is None: path = self.get_path_from_user() # TODO:当窗口返回的是工作目录是空字符串,重复要求用户设置 if path == '': self.set_work_dir(False) else: self.changeworkdir(path, isdialogflag) self.lineEdit.setText(path) # 重设记事本模块工作目录 self.notepad.changeworkdir(self.workdir) self.statusbar.showMessage("RSA:change work dir to /" + path) def set_work_dir(self, firstworkdirflag=False): if firstworkdirflag is True: text = "没有找到默认数据文件夹,是否浏览目录设置" else: text = "未选择工作目录,是否浏览目录设置" self.lineEdit.setText("Working directory") reply = QMessageBox.question(self, "温馨提示", text, QMessageBox.Yes | QMessageBox.Cancel, QMessageBox.Cancel) if reply == QMessageBox.Yes: # 用户点击Yes,设置工作目录,模拟用户点击浏览按钮 self.on_browsebutton_clicked() if reply == QMessageBox.Cancel: pass # 我是不想搞这个额外的方法的,但是如果不做分离上面两个函数不正常 def get_path_from_user(self): filedialog = QFileDialog() filedialog.setViewMode(QFileDialog.Detail) path = QFileDialog.getExistingDirectory( self, '请选择数据文件夹', os.environ['userprofile'] + os.path.sep + 'desktop') return path @pyqtSlot() def on_searchbutton_clicked(self): self.statusbar.showMessage("RSA:search dir is " + self.workdir) self.searchdialog.show() def searchdialogitemdoubleclicked(self, event): index = event.text() if os.path.isdir(index): self.on_browsebutton_clicked(index, isdialogflag=True) self.searchdialog.close() elif os.path.isfile(index): path = os.path.dirname(index) self.on_browsebutton_clicked(path, isdialogflag=True) self.mouseindex = index self.plotfile() self.searchdialog.close() def aboutthisprogram(self): self.statusbar.showMessage("RSA:about this program") self.aboutwin.show() def helpmanual(self): self.statusbar.showMessage("RSA:start help manual") self.helpwin.show() def findpeakswin(self): # 检查绘图板上是否存在图形 if self.plotcount == 1: self.statusbar.showMessage("RSA:start find peaks /" + self.mouseindex.lstrip(self.workdir)) self.findpeaksdialog.show() else: self.statusbar.showMessage( "RSA:plotcount is {},find peaks will not run".format( self.plotcount)) QMessageBox.information( self, "提示", "findpeas仅能在绘图板上有一个图形时运行\n当前绘图数为{}".format(self.plotcount), QMessageBox.Close, QMessageBox.Close) def findpeaksplot(self): data = self.lastplotdata.iloc[:, 0].values # 这个值用来对齐绘图板显示的x轴坐标和返回的峰x轴坐标的差异 firstindex = int(self.lastplotdata.index[0]) peaks = self.findpeaksdialog.find_peaks(data) self.findpeaksdialog.textEdit.clear() self.findpeaksdialog.textEdit.setEnabled(True) self.findpeaksdialog.textEdit.append("peak index,peak values") # 添加元素前清空一次 self.clearpeaksmark() for peak in peaks: if self.findpeaksdialog.peakmarkcheckbox.isChecked(): arrow = pg.ArrowItem(pos=(peak, data[peak]), angle=-90) self.plotItem.addItem(arrow) self.findpeaksdialog.peaksmarklist.append(arrow) if self.findpeaksdialog.peaktextchebox.isChecked(): text = pg.TextItem("peak") text.setPos(peak, data[peak]) self.plotItem.addItem(text) self.findpeaksdialog.peaksmarklist.append(text) self.findpeaksdialog.textEdit.append("[" + str(peak + firstindex) + "," + str(data[peak]) + "]") def clearfindpeaks(self): self.clearpeaksmark() self.findpeaksdialog.clear() def clearpeaksmark(self): for mark in self.findpeaksdialog.peaksmarklist: self.plotItem.removeItem(mark) def crosshaircheckboxstateChanged(self, checkbox): # 防止未绘图连续点击两次checkbox程序崩溃 if self.plotcount == 0: pass else: # 十字光标相关设置,添加元素到绘图元件中 if checkbox.isChecked(): self.mouseTrackingLabel = pg.TextItem() # 创建一个文本项 self.plotItem.addItem(self.mouseTrackingLabel) # 在图形部件中添加文本项 self.vLine = pg.InfiniteLine( angle=90, movable=False, ) # 创建一个垂直线条 self.hLine = pg.InfiniteLine( angle=0, movable=False, ) # 创建一个水平线条 self.plotItem.addItem(self.vLine, ignoreBounds=True) # 在图形部件中添加垂直线条 self.plotItem.addItem(self.hLine, ignoreBounds=True) # 在图形部件中添加水平线条 self.showgridcheckboxstateChanged( self.showgridcheckbox) # 显示网格 # 如果用户取消了checkbox的状态,那就删除这三个item # 判断元素是否存在,因为三个元素是统一添加、统一删除的,判断一个元素是不是存在就行 flag = True try: self.mouseTrackingLabel except AttributeError: flag = False if checkbox.isChecked() is False and flag is True: self.plotItem.removeItem(self.hLine) self.plotItem.removeItem(self.vLine) self.plotItem.removeItem(self.mouseTrackingLabel) def showgridcheckboxstateChanged(self, checkbox): if checkbox.checkState(): self.plotItem.showGrid(x=True, y=True, alpha=get_grid_alpha()) else: self.plotItem.showGrid(x=False, y=False) def mouseMoved(self, event): # 必须勾选crosshair的checkbox且绘图板上有图形才会进行鼠标追踪 if self.crosshaircheckbox.isChecked() and self.plotcount >= 1: if event is None: pass else: pos = event # 获取事件的鼠标位置 try: # 如果鼠标位置在绘图部件中 if self.plotItem.sceneBoundingRect().contains(pos): mousePoint = self.plotItem.vb.mapSceneToView( pos) # 转换鼠标坐标 index = int(mousePoint.x()) # 鼠标所处的X轴坐标 # pos_y = int(mousePoint.y()) # 鼠标所处的Y轴坐标 # TODO:如果多次载入数据长度不一样,这里可能会引发错误 if -1 < index < len(self.axis_y_data_arr[0].index): # 在label中写入HTML self.mouseTrackingLabel.setHtml( self.generate_mousetracking_label( self.plotcount, index)) self.mouseTrackingLabel.setPos( mousePoint.x(), mousePoint.y()) # 设置label的位置 # 设置垂直线条和水平线条的位置组成十字光标 self.vLine.setPos(mousePoint.x()) self.hLine.setPos(mousePoint.y()) except Exception as e: QMessageBox.information(self, "提示", "鼠标追踪错误\n{}".format(e), QMessageBox.Close, QMessageBox.Close) def generate_mousetracking_label(self, count, index): labletext = "" for i in range(count): labletext = labletext + "<p style='color:white'><strong>{}:{} {}:{}</strong></p>"\ .format(get_x_axis_lable(), self.axis_x_dict_arr[i][index], get_y_axis_lable(), self.axis_y_data_arr[i].iloc[index].values) return labletext def closeEvent(self, QCloseEvent): # 退出程序确认,使用QMessageBox提示 reply = QMessageBox.warning(self, "温馨提示", "即将退出RSA, 确定?", QMessageBox.Yes | QMessageBox.Cancel, QMessageBox.Yes) if reply == QMessageBox.Yes: QCloseEvent.accept() # 关闭所有子窗体 self.aboutwin.close() self.helpwin.close() self.searchdialog.close() self.findpeaksdialog.close() self.notepad.close() if reply == QMessageBox.Cancel: QCloseEvent.ignore()
class MyTreeView(QTreeView): # Overwritten def __init__(self, main): super().__init__() self.main = main self.model = QFileSystemModel() current_path = os.path.abspath(os.getcwd()) self.model.setRootPath(current_path) self.setModel(self.model) self.setRootIndex(self.model.index(current_path)) self.setColumnWidth(0, 250) self.setSortingEnabled(True) self.sortByColumn(0, 0) self.setEditTriggers(QTreeView.NoEditTriggers) self.model.setReadOnly(False) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.context_menu) # ___ _ _ __ __ # / __|___ _ _| |_ _____ _| |_| \/ |___ _ _ _ _ # | (__/ _ \ ' \ _/ -_) \ / _| |\/| / -_) ' \ || | # \___\___/_||_\__\___/_\_\\__|_| |_\___|_||_\_,_| def context_menu(self): menu = QMenu() open_ = menu.addAction("Open / Display") open_.triggered.connect(self.c_m_open) web = menu.addAction("Load webView file") web.triggered.connect(self.c_m_web_load) menu.addSeparator() rename = menu.addAction("Rename") rename.triggered.connect(self.c_m_rename) copy_path = menu.addAction("Copy path") copy_path.triggered.connect(self.c_m_copy_path) duplicate = menu.addAction("Duplicate") duplicate.triggered.connect(self.c_m_duplicate) show_in_explorer = menu.addAction("Show in explorer") show_in_explorer.triggered.connect(self.c_m_explorer) menu.addSeparator() delete = menu.addAction("Delete") delete.triggered.connect(self.c_m_delete) cursor = QCursor() menu.exec_(cursor.pos()) def c_m_open(self): """"Abre un archivo o despliega un fichero""" index = self.currentIndex() path = self.model.filePath(index) if os.path.isfile(path): self.main.open_file(path) else: self.setExpanded(index, True) def c_m_web_load(self): """Abre en el webViewer el fichero""" index = self.currentIndex() path = self.model.filePath(index) if os.path.isfile(path): self.main.webView.update_by_file(path) else: pass def c_m_rename(self): """"Renombrar archivo o directorio desde el TreeView""" index = self.currentIndex() self.edit(index) def c_m_copy_path(self): """"Copia la ruta de un archivo o directorio""" index = self.currentIndex() path = self.model.filePath(index) pyperclip.copy(path) def c_m_duplicate(self): """"Duplica un archivo o directorio""" index = self.currentIndex() path = self.model.filePath(index) if os.path.isfile(path): filename, file_extension = os.path.splitext(path) copyfile(path, f"{filename}(copy){file_extension}") else: copytree(path, path + "(copy)") def c_m_explorer(self): """"Abre el explorador en el path padre de un archivo o directorio""" index = self.currentIndex() path = self.model.filePath(index) path = os.path.realpath(path) path = os.path.dirname(path) os.startfile(path) def c_m_delete(self): """"Borra un archivo o directorio (lo manda a la papelera de reciclaje)""" index = self.currentIndex() path = self.model.filePath(index) path = os.path.realpath(path) # if os.path.isfile(path): # os.remove(path) # else: # rmtree(path) qm = QMessageBox ret = qm.question( self, '', f"Are you sure to delete '{os.path.basename(path)}' ?", qm.Yes | qm.No, defaultButton=qm.No) if ret == qm.Yes: send2trash(path)
class FileManager: """ Create a popup window to select a folder / file Global Varables --------------- item_index: PyQt5 index element to have a global reference to currently clicked element callback_func: Global reference to set the callback function passed into create_tree_view_popup popup_window: Global reference to the QWidget window which serves as a popup container for the TreeView """ # pylint: disable=no-self-use def __init__(self, width=0): """ Initializes required variables by the class """ self.width = width self.item_index = None self.callback_func = None self.popup_window = None self.model = None def create_tree_view(self, start_path="/home", callback=None): """ Display the tree view to choose a folder """ file_manager = QTreeView() self.callback_func = callback self.model = QFileSystemModel() self.model.setRootPath(start_path) # for ViewType in (QColumnView, QTreeView): file_manager.setModel(self.model) # hide all columns except the filename for i in range(1, self.model.columnCount()): file_manager.hideColumn(i) file_manager.setRootIndex(self.model.index(start_path)) file_manager.setFixedWidth(self.width) file_manager.setWordWrap(True) file_manager.clicked.connect(self.item_clicked) return {"file_manager": file_manager, "file_model": self.model} def create_file_dialog(self, start_path="/home"): """ Create a file dialog window """ file_dialog = QFileDialog() file_dialog.setFileMode(QFileDialog.AnyFile) file_dialog.setDirectory(start_path) return file_dialog def create_tree_view_popup(self, start_path="/home", callback=None, directory=False): """ Function which creates a TreeView in a external Window""" # self.popup_window = QWidget() actual_path = None if not os.path.isdir(start_path) and os.path.isfile(start_path): path_arr = start_path.split('/') path_arr.pop(len(path_arr) - 1) actual_path = '/'.join(e for e in path_arr) else: actual_path = "/home" if not directory: filename = QFileDialog.getOpenFileName(None, "Open File", actual_path) if filename[0]: callback({"file_path": filename[0]}) else: directory = QFileDialog.getExistingDirectory( None, 'Select a Folder:', actual_path, QFileDialog.ShowDirsOnly) callback({"dir_path": directory}) def item_clicked(self, index): """ Helper function to keep track of the selected item in the TreeView """ self.item_index = index self.select_item() def select_item(self): """ Passes the current selected item to the callback function and closes the window """ # get the index of the currently chosen item index_item = self.model.index(self.item_index.row(), 0, self.item_index.parent()) # get the file path of this item file_path = self.model.filePath(index_item) # return it with a callback self.callback_func({"file_path": file_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('~'), '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 LocalPathView(QTreeView): def __init__ (self): super(LocalPathView, self).__init__() self._model = QFileSystemModel() self._model.setFilter(QDir.Dirs | QDir.Drives | QDir.NoDotAndDotDot | QDir.AllDirs) self._model.setRootPath('') self.setModel(self._model ) self.hideColumn(1); # removing Size Column self.hideColumn(2); # removing Type Column self.setAnimated(False) self.setSortingEnabled(True) self.header().setSortIndicator(0, Qt.AscendingOrder) width = self.size().width() >> 1 self.setColumnWidth(0, width*0.7) self.setColumnWidth(1, width*0.3) index = self._model.index(QDir.currentPath()) self.selectionModel().setCurrentIndex(index, QItemSelectionModel.Select | QItemSelectionModel.Rows) self.expand(index) self.scrollTo(index) @property def selectedDir(self): return self._model.filePath(self.selectionModel().selectedIndexes()[0])