class DisplayContainer(QWidget): """ This code is to create an area for display widgets such as graphs to be shown to the user. """ def __init__(self, parent, callback, ch): self.logger = logging.getLogger(__name__) self.logger.addHandler(ch) self.logger.debug("Initializing") super().__init__(parent) self.__callback = callback self.setLayout(QVBoxLayout()) self.__scroll_area = QScrollArea(self) self.__scroll_area.verticalScrollBar().valueChanged.connect(self.__slider_changed_notifier) self.__scroll_area.setWidgetResizable(True) self.layout().addWidget(self.__scroll_area) contents = QWidget(self) contents.setGeometry(QRect(0, 0, 335, 499)) contents.setLayout(QVBoxLayout()) self.__scroll_area.setWidget(contents) self.__list_of_displays = [] self.logger.debug("Initialized") def add_display(self, display): """ Add a display, typically a graph, to the set of displays to be displayed in the display area. """ self.logger.debug("running") self.__list_of_displays.append(display) self.__refresh() self.logger.debug("done") def remove_display(self, display): """ Remove a display, typically a graph, from the set of displays if it exists. """ self.logger.debug("running") if display in self.__list_of_displays: self.__list_of_displays.remove(display) self.__refresh() self.logger.debug("done") def __refresh(self): """ Rebuild display area to refresh the view. """ self.logger.debug("running") new_contents = QWidget(self) new_contents.setGeometry(QRect(0, 0, 335, 499)) new_contents.setLayout(QVBoxLayout()) for display in self.__list_of_displays: new_contents.layout().addWidget(display) self.__scroll_area.setWidget(new_contents) self.logger.debug("done") def __slider_changed_notifier(self): """ Notify controller that the user scrolled the display area. """ self.logger.debug("running") self.__callback() self.logger.debug("done")
class AdjustChunkBrightContrastDlg(QtWidgets.QDialog): # path = '' # image = Image def __init__(self, parent): QtWidgets.QDialog.__init__(self, parent) self.setWindowTitle( "ADJUST PHOTOS BRIGHTNESS - CONTRAST, CMG (MAROC)") # self.adjustSize() self.setMaximumHeight(880) self.createParamsGridLayout() self.createButtonsGridLayout() self.createProgressBar() self.createImageViewerLayout() vbox = QtWidgets.QVBoxLayout() vbox.addWidget(self.groupBoxParams) vbox.addWidget(self.groupBoxViewer) vbox.addWidget(self.groupBoxProgressBar) vbox.addWidget(self.groupBoxButtons) self.setLayout(vbox) self.exec() def createImageViewerLayout(self): self.groupBoxViewer = QtWidgets.QGroupBox() gridViewerLayout = QtWidgets.QGridLayout() self.scaleFactor = 0.0 self.imageLabel = QtWidgets.QLabel(self) self.imageLabel.setBackgroundRole(QtGui.QPalette.Base) self.imageLabel.setSizePolicy( QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Ignored) self.imageLabel.setScaledContents(True) self.scrollArea = QScrollArea() self.scrollArea.setBackgroundRole(QPalette.Dark) self.scrollArea.setWidget(self.imageLabel) self.scrollArea.setMinimumHeight(605) # self.scrollArea.setMaximumHeight(605) self.scrollArea.setMinimumWidth(830) self.scrollArea.setMaximumWidth(830) self.getChunk() self.getPaths() self.getImage(0) self.scrollArea.setWidgetResizable(False) self.normalSize() self.scaleImage(0.16) gridViewerLayout.addWidget(self.scrollArea, 1, 0) self.createViewerButtons() gridViewerLayout.addWidget(self.groupBoxViewerBtn, 0, 0) self.groupBoxViewer.setLayout(gridViewerLayout) def createViewerButtons(self): self.groupBoxViewerBtn = QtWidgets.QGroupBox() gridViewerBtnLayout = QtWidgets.QGridLayout() self.btnNextPhoto = QtWidgets.QPushButton("->") self.btnNextPhoto.setFixedSize(23, 23) self.btnPreviousPhoto = QtWidgets.QPushButton("<-") self.btnPreviousPhoto.setFixedSize(23, 23) self.btnZoomIn = QtWidgets.QPushButton("+") self.btnZoomIn.setFixedSize(23, 23) self.btnZoomOut = QtWidgets.QPushButton("-") self.btnZoomOut.setFixedSize(23, 23) # self.btnZoomOut = QtWidgets.QPushButton("-") # self.btnZoomOut.setFixedSize(23, 23) gridViewerBtnLayout.addWidget(self.btnZoomIn, 0, 0) gridViewerBtnLayout.addWidget(self.btnZoomOut, 0, 1) gridViewerBtnLayout.addWidget(self.btnPreviousPhoto, 0, 3) gridViewerBtnLayout.addWidget(self.btnNextPhoto, 0, 4) QtCore.QObject.connect( self.btnZoomIn, QtCore.SIGNAL("clicked()"), self.zoomIn) QtCore.QObject.connect( self.btnZoomOut, QtCore.SIGNAL("clicked()"), self.zoomOut) QtCore.QObject.connect( self.btnNextPhoto, QtCore.SIGNAL("clicked()"), self.nextPhoto) QtCore.QObject.connect( self.btnPreviousPhoto, QtCore.SIGNAL("clicked()"), self.previousPhoto) self.groupBoxViewerBtn.setLayout(gridViewerBtnLayout) def createButtonsGridLayout(self): self.groupBoxButtons = QtWidgets.QGroupBox() gridBtnLayout = QtWidgets.QGridLayout() self.btnQuit = QtWidgets.QPushButton("Cancel") self.btnQuit.setFixedSize(150, 23) self.btnSubmit = QtWidgets.QPushButton("OK") self.btnSubmit.setFixedSize(150, 23) gridBtnLayout.addWidget(self.btnSubmit, 0, 0) gridBtnLayout.addWidget(self.btnQuit, 0, 1) self.btnSubmit.setEnabled(False) QtCore.QObject.connect(self.btnQuit, QtCore.SIGNAL( "clicked()"), self, QtCore.SLOT("reject()")) QtCore.QObject.connect( self.btnSubmit, QtCore.SIGNAL("clicked()"), self.adjustChunkPhotos) self.groupBoxButtons.setLayout(gridBtnLayout) def createParamsGridLayout(self): self.groupBoxParams = QtWidgets.QGroupBox('Adjustment parameters') gridParamsLayout = QtWidgets.QGridLayout() gridParamsLayout.setHorizontalSpacing(50) self.label_chunk = QtWidgets.QLabel('Chunk : ') self.chunksBox = QtWidgets.QComboBox() self.chunksBox.resize(200, 23) self.getChunks() for chunk in self.chunks: self.chunksBox.addItem(chunk.label, chunk.key) self.label_brightness = QtWidgets.QLabel('Image brightness (%): ') self.brightness = QtWidgets.QSpinBox() self.brightness.setMaximum(500) self.brightness.setSingleStep(20) self.brightness.setMinimum(0) self.brightness.setValue(100) self.label_contrast = QtWidgets.QLabel('Image contrast (%): ') self.contrast = QtWidgets.QSpinBox() self.contrast.setMaximum(500) self.contrast.setSingleStep(20) self.contrast.setMinimum(0) self.contrast.setValue(100) self.label_folder = QtWidgets.QLabel('Select folder : ') self.btn_select_folder = QtWidgets.QPushButton("Select...") self.btn_select_folder.setFixedSize(150, 23) self.path_label = QtWidgets.QLabel('Selected Path : ...') self.space = QtWidgets.QLabel(' ') self.chunk_create_label = QtWidgets.QLabel("Create new Chunk") self.chkCreateChunk = QtWidgets.QCheckBox() self.chkCreateChunk.setChecked(True) # adding widget gridParamsLayout.addWidget(self.label_chunk, 0, 0) gridParamsLayout.addWidget(self.chunksBox, 0, 1) gridParamsLayout.addWidget(self.label_folder, 0, 2) gridParamsLayout.addWidget(self.btn_select_folder, 0, 3) gridParamsLayout.addWidget(self.label_brightness, 1, 0) gridParamsLayout.addWidget(self.brightness, 1, 1) gridParamsLayout.addWidget(self.path_label, 1, 2) gridParamsLayout.addWidget(self.label_contrast, 2, 0) gridParamsLayout.addWidget(self.contrast, 2, 1) gridParamsLayout.addWidget(self.chunk_create_label, 2, 2) gridParamsLayout.addWidget(self.chkCreateChunk, 2, 3) QtCore.QObject.connect( self.btn_select_folder, QtCore.SIGNAL("clicked()"), self.selectFolder) self.chunksBox.currentIndexChanged.connect(self.getChunk) self.brightness.valueChanged.connect(self.getPixmapFromEnhance) self.contrast.valueChanged.connect(self.getPixmapFromEnhance) self.groupBoxParams.setLayout(gridParamsLayout) def createProgressBar(self): self.groupBoxProgressBar = QtWidgets.QGroupBox() gridProgressBar = QtWidgets.QGridLayout() self.progressBar = QtWidgets.QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) gridProgressBar.addWidget(self.progressBar, 0, 0) self.groupBoxProgressBar.setLayout(gridProgressBar) def zoomIn(self): self.scaleImage(1.25) def zoomOut(self): self.scaleImage(0.8) def normalSize(self): self.imageLabel.adjustSize() self.scaleFactor = 1.0 def scaleImage(self, factor): self.scaleFactor *= factor self.imageLabel.resize( self.scaleFactor * self.imageLabel.pixmap().size()) self.adjustScrollBar(self.scrollArea.horizontalScrollBar(), factor) self.adjustScrollBar(self.scrollArea.verticalScrollBar(), factor) def adjustScrollBar(self, scrollBar, factor): scrollBar.setValue(int(factor * scrollBar.value() + ((factor - 1) * scrollBar.pageStep()/2))) def fitToWindow(self, fitToWindow): self.scrollArea.setWidgetResizable(fitToWindow) if not fitToWindow: self.normalSize() def getChunks(self): self.chunks = Metashape.app.document.chunks if len(self.chunks) == 0: Metashape.app.messageBox('No chunk in project') def getChunk(self): chunk_key = self.chunksBox.currentData() self.chunk = doc.findChunk(chunk_key) self.brightness.setValue(100) self.contrast.setValue(100) self.getPaths() self.getImage(0) def selectFolder(self): directoryPath = QtWidgets.QFileDialog.getExistingDirectory( self, "Select Directory") dossier = directoryPath.split('/')[-1] path = 'Selected Path : {}'.format(directoryPath) self.path_label.setText(path) self.btnSubmit.setEnabled(True) self.path_folder = directoryPath def getPaths(self): self.paths = [] for c in self.chunk.cameras: path = c.photo.path self.paths.append(path) if len(self.paths) == 0: Metashape.app.messageBox('No photos in this chunk') def getImage(self, index): self.path_photo = self.paths[index] self.image = QtGui.QPixmap(self.path_photo) self.imageLabel.setPixmap(self.image) def nextPhoto(self): index = self.paths.index(self.path_photo) if index == len(self.paths) - 1: index = 0 else: index = index + 1 self.path_photo = self.paths[index] self.getPixmapFromEnhance() def previousPhoto(self): index = self.paths.index(self.path_photo) if index == 0: index = len(self.paths) - 1 else: index = index - 1 self.path_photo = self.paths[index] self.getPixmapFromEnhance() def adjustImage(self, image): brghitness = self.brightness.value() / 100 contrast = self.contrast.value() / 100 imageEnhancer = ImageEnhance.Brightness(image) imgBright = imageEnhancer.enhance(brghitness) imageEnhancer = ImageEnhance.Contrast(imgBright) imgContrast = imageEnhancer.enhance(contrast) return imgContrast def getPixmapFromEnhance(self): image = Image.open(self.path_photo) img = self.adjustImage(image) self.image = img.toqimage() self.image = QtGui.QPixmap(self.image) self.imageLabel.setPixmap(self.image) image.close() def get_exif(self, image): exif = image._getexif() return exif def add_new_chunk(self, images): doc = Metashape.app.document new_chunk = doc.addChunk() new_chunk.label = 'Adjusted ' + self.chunk.label new_chunk.addPhotos(images) def copyPhots(self, c): self.i = self.i + 1 self.progressBar.setValue(self.i) source = c.photo.path destination = self.path_folder path_without_drive = os.path.splitdrive(source)[1] subfolder = os.path.splitext(path_without_drive)[0] path_to_photo = os.path.split(path_without_drive)[0] folders = path_to_photo.split('/') path_dist = destination + path_to_photo path_dist = path_dist.replace(self.commun_without_drive, '') try: if not os.path.exists(path_dist): os.makedirs(path_dist) image = Image.open(source) exif = self.get_exif(image) enhancer = self.adjustImage(image) path = path_dist + '/' + c.label + '.jpg' enhancer.save( path, exif=image.info["exif"]) self.imageList.append(path) image.close() except RuntimeError: Metashape.app.messageBox('error') def adjustChunkPhotos(self): print("Import Adjust Photos Script started...") self.imageList = [] commun = os.path.commonpath(self.paths) commun_without_drive = os.path.splitdrive(commun)[1] self.commun_without_drive = commun_without_drive.replace('\\', '/') total = len(self.chunk.cameras) self.progressBar.setMaximum(total) self.i = 0 # with concurrent.futures.ThreadPoolExecutor() as executor: # executor.map(self.copyPhots, self.chunk.cameras) for c in self.chunk.cameras: self.copyPhots(c) QtWidgets.QApplication.processEvents() if self.chkCreateChunk.isChecked(): self.add_new_chunk(self.imageList) self.close() print("Script finished!") # Metashape.app.messageBox('Adjusting and Copy successful !') return True
class ItemWidget(QWidget): ItemUpdated = Signal() _KEYS = ( "type", "title", "authors", "authors_bais", "editors", "editors_bais", "abstract", "date", "publication", "volume", "issue", "pages", "year", "edition", "series", "publisher", "isbns", "institution", "degree", "texkey", "inspire_id", "arxiv_id", "dois", "urls", "files" ) _FORMAT_TYPE = { "A": "Article", "B": "Book", "C": "Book Chapter", "N": "Note", "P": "Conference Proceedings", "R": "Report", "T": "Thesis" } _FORMAT_FUNCTIONS = { "type": lambda x: ItemWidget._FORMAT_TYPE.get(x, ""), "authors": "\n".join, "editors": "\n".join, "isbns": "\n".join, # Alternatively one could use # lambda x: "\n".join([a.split(",", 1)[0] for a in x]) "inspire_id": lambda x: str(x) if x is not None else None, "year": lambda x: str(x) if x is not None else None, "dois": "\n".join, "urls": "\n".join } def __init__(self, parent=None): super().__init__(parent) self._source = None self._table = None self._id = -1 self._updating = False self._scroll = QScrollArea() # self._scroll.setBackgroundRole(QPalette.Base) self._scroll.setWidgetResizable(True) self._date = LineEdit() min_height = self._date.sizeHint().height() self._type = ComboBox() self._title = MultiLineTextEdit(min_height) self._authors = LineSplitTextEdit(min_height) self._editors = LineSplitTextEdit(min_height) self._abstract = MultiLineTextEdit(min_height) self._publication = LineEdit() self._volume = LineEdit() self._issue = LineEdit() self._pages = LineEdit() self._year = LineEdit() self._edition = LineEdit() self._series = LineEdit() self._publisher = LineEdit() self._isbns = LineSplitTextEdit(min_height) self._institution = LineEdit() self._degree = LineEdit() self._texkey = LineEdit() self._inspire_id = LineEdit() self._arxiv_id = LineEdit() self._dois = LineSplitTextEdit(min_height) self._urls = LineSplitTextEdit(min_height) self._files = FileList() for (k, v) in ItemWidget._FORMAT_TYPE.items(): self._type.addItem(v, k) # self._type.currentIndexChanged[int].connect(self._RefreshTypeFields) bold_font = self._title.document().defaultFont() bold_font.setBold(True) self._title.document().setDefaultFont(bold_font) self._files.FileDropRequested.connect(self._DropFile) self._fields = { "type": self._type, "title": self._title, "authors": self._authors, "editors": self._editors, "abstract": self._abstract, "date": self._date, "publication": self._publication, "volume": self._volume, "issue": self._issue, "pages": self._pages, "year": self._year, "edition": self._edition, "series": self._series, "publisher": self._publisher, "isbns": self._isbns, "institution": self._institution, "degree": self._degree, "texkey": self._texkey, "inspire_id": self._inspire_id, "arxiv_id": self._arxiv_id, "dois": self._dois, "urls": self._urls } self._details_frame = QGroupBox() self._details_layout = QFormLayout() self._scroll_widget = QWidget() self._SetupScrollUI() self._scroll.setWidget(self._scroll_widget) self._scroll_widget.hide() self._save = QToolButton() self._save.setIcon(QIcon(icons.SAVE)) self._save.clicked.connect(self._Save) self._reload = QToolButton() self._reload.setIcon(QIcon(icons.RELOAD)) self._reload.clicked.connect(self.DisplayItem) self._file_add = QToolButton() self._file_add.setIcon(QIcon(icons.FILE_ADD)) self._file_add.clicked.connect(self._AddFile) self._tool_widget = QWidget() self._SetupToolUI() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self._scroll) layout.addWidget(self._tool_widget) self.setLayout(layout) self.Clear() def _SetupScrollUI(self): self._details_layout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) self._details_layout.addRow("Journal", self._publication) self._details_layout.addRow("Editors", self._editors) self._details_layout.addRow("Volume", self._volume) self._details_layout.addRow("Issue", self._issue) self._details_layout.addRow("Pages", self._pages) self._details_layout.addRow("Edition", self._edition) self._details_layout.addRow("Series", self._series) self._details_layout.addRow("Publisher", self._publisher) self._details_layout.addRow("ISBNs", self._isbns) self._details_layout.addRow("Institution", self._institution) self._details_layout.addRow("Degree", self._degree) self._details_layout.addRow("Year", self._year) self._details_layout.setVerticalSpacing(0) self._details_frame.setLayout(self._details_layout) form_layout = QFormLayout() form_layout.setContentsMargins(0, 0, 0, 0) form_layout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) form_layout.addRow("Type", self._type) form_layout.addRow("Title", self._title) form_layout.addRow("Authors", self._authors) form_layout.addRow("Abstract", self._abstract) form_layout.addRow("Date", self._date) form_layout.addRow("", self._details_frame) form_layout.addRow("BibTeX", self._texkey) form_layout.addRow("INSPIRE", self._inspire_id) form_layout.addRow("arXiv", self._arxiv_id) form_layout.addRow("DOIs", self._dois) form_layout.addRow("URLs", self._urls) form_layout.addRow("Files", self._files) form_layout.setVerticalSpacing(0) form = QWidget() form.setLayout(form_layout) scroll_layout = QVBoxLayout() scroll_layout.addWidget(form) scroll_layout.addStretch(1) self._scroll_widget.setLayout(scroll_layout) def _SetupToolUI(self): tool_layout = QHBoxLayout() tool_layout.setContentsMargins(0, 0, 0, 0) tool_layout.addWidget(self._file_add) tool_layout.addStretch(1) tool_layout.addWidget(self._reload) tool_layout.addWidget(self._save) self._tool_widget.setLayout(tool_layout) self._reload.setEnabled(False) self._save.setEnabled(False) self._file_add.setEnabled(False) for w in self._fields.values(): w.Edited.connect(self._EnableRefreshSave) # def _RefreshTypeFields(self, index): # pass def _EnableRefreshSave(self): self._reload.setEnabled(True) self._save.setEnabled(True) def _Save(self): data = {} for (k, w) in self._fields.items(): data[k] = w.Read() authors_raw = [" ".join(a.split()) for a in data["authors"]] authors = [] authors_bais = [] for a in authors_raw: (n, b) = ItemWidget._ParseAuthor(a) authors.append(n) authors_bais.append(b) data["authors"] = authors data["authors_bais"] = authors_bais editors_raw = [" ".join(e.split()) for e in data["editors"]] editors = [] editors_bais = [] for e in editors_raw: (n, b) = ItemWidget._ParseAuthor(e) editors.append(n) editors_bais.append(b) data["editors"] = editors data["editors_bais"] = editors_bais if data["date"] is not None: try: data["date"] = ItemWidget._ParseDate(data["date"]) except: del data["date"] if data["year"] is not None: try: data["year"] = datetime.strptime(data["year"], "%Y").strftime("%Y") except: del data["year"] if data["inspire_id"] is not None: try: data["inspire_id"] = int(data["inspire_id"]) except: del data["inspire_id"] self._table.EditRow(self._id, data) self.ItemUpdated.emit() def _AddFile(self): files_dir = self._source.FilesDir() if files_dir is None: QMessageBox.critical(None, "Error", "Cannot access storage folder.") return (file_path, _) = QFileDialog.getOpenFileName( None, "Open Document", files_dir, "Documents (*.pdf *.djvu)" ) if file_path == "": return file_name = os.path.basename(file_path) try: renaming = self._source.SaveFiles((file_path,)) except: QMessageBox.critical(None, "Error", "Error while copying the file.") else: self._AppendFile(renaming.get(file_name, file_name)) def _AppendFile(self, file_name): data = self._table.GetRow(self._id, ("files",)) if file_name in data: return data["files"].append(file_name) # Here self._updating is used to prevent calls to DisplayItem() # triggered by an Updated() signal emitted by the database. self._updating = True self._table.EditRow(self._id, data) self._updating = False self._files.Write(data["files"]) def _DropFile(self, file_name): data = self._table.GetRow(self._id, ("files",)) data["files"] = [f for f in data["files"] if f != file_name] # Here self._updating is used to prevent calls to DisplayItem() # triggered by an Updated() signal emitted by the database. self._updating = True self._table.EditRow(self._id, data) self._updating = False self._files.Write(data["files"]) def SetLocalSource(self, source): if self._source == source: return self._source = source self._SetTable(source.table) def SetTable(self, database_table): if self._table == database_table: return self._source = None self._SetTable(database_table) def _SetTable(self, database_table): if self._table is not None: self._table.Cleared.disconnect(self.Clear) self._table = database_table self._table.Cleared.connect(self.Clear) if self._source is None: self._files.setEnabled(False) self._files.SetFolder(None) else: self._files.setEnabled(True) try: self._files.SetFolder(self._source.FilesDir()) except: self._files.SetFolder(None) def Clear(self): self._scroll_widget.hide() self._scroll.verticalScrollBar().hide() def DisplayItem(self, id_=False): if self._updating: return if id_: self._id = id_ if self._id == -1: self.Clear() self._reload.setEnabled(False) self._save.setEnabled(False) self._file_add.setEnabled(False) return record = self._table.GetRow(self._id, ItemWidget._KEYS) authors = [] for (a, b) in zip(record["authors"], record["authors_bais"]): if b is None: authors.append(a) else: authors.append(a + " (" + b + ")") record["authors"] = authors editors = [] for (e, b) in zip(record["editors"], record["editors_bais"]): if b is None: editors.append(e) else: editors.append(e + " (" + b + ")") record["editors"] = editors for (k, v) in ItemWidget._FORMAT_FUNCTIONS.items(): record[k] = v(record[k]) for (k, w) in self._fields.items(): w.Write(record[k]) self._files.Write(record["files"]) self._scroll.verticalScrollBar().show() self._scroll_widget.show() self._reload.setEnabled(False) self._save.setEnabled(False) if self._source is not None: self._file_add.setEnabled(True) @staticmethod def _ParseAuthor(author): split = author.split("(", 1) author = split[0].strip() if len(split) == 1: return(author, None) bai = split[1].split(")", 1) if len(bai) == 1: return(author, None) bai = bai[0].replace(" ", "") # The sanity check on the BAI could be further refined return(author, bai) @staticmethod def _ParseDate(date_string): n_dashes = date_string.count("-") if n_dashes == 2: return datetime.strptime(date_string, "%Y-%m-%d").strftime("%Y-%m-%d") if n_dashes == 1: return datetime.strptime(date_string, "%Y-%m").strftime("%Y-%m") return datetime.strptime(date_string, "%Y").strftime("%Y")
class HomeFeed(QWidget): def __init__(self): super(HomeFeed, self).__init__() self.run_get_feed_thread() self.feed = [] self.page = 1 self.loading = False self.layout = QStackedLayout() self.layout.setMargin(0) self.loading_label = QLabel('Loading...', alignment=Qt.AlignCenter) self.layout.addWidget(self.loading_label) self.layout.setCurrentWidget(self.loading_label) self.page_widget = QScrollArea() self.page_widget.setWidgetResizable(True) self.page_widget.viewport().installEventFilter(self) widget = QWidget(self.page_widget) widget.setMinimumWidth(350) self.page_widget.setWidget(widget) self.flow_layout = FlowLayout(widget) self.flow_layout.setContentsMargins(25, 25, 25, 25) self.layout.addWidget(self.page_widget) self.setLayout(self.layout) def run_get_feed_thread(self): self.thread = RunThread(self.get_feed, self.on_feed_receive) def eventFilter(self, source, event): if (event.type() == QEvent.Wheel and source is self.page_widget.viewport() and not self.loading): scrollbar = self.page_widget.verticalScrollBar() y = scrollbar.value() bottom = scrollbar.maximum() if y >= bottom: self.page += 1 self.loading = True self.run_get_feed_thread() return super(HomeFeed, self).eventFilter(source, event) def get_feed(self): spider = CoreRadioSpider() self.feed = spider.get_home_feed(page=self.page) return True def on_feed_receive(self): if len(self.feed) > 0: for item in self.feed: preview_widget = SongPreview(artwork=item['artwork'], title=item['title'], url=item['href']) self.flow_layout.addWidget(preview_widget) self.loading = False self.layout.setCurrentWidget(self.page_widget) else: self.loading_label.setText( "Something wen't wrong, please try again")
class MainWindow(QMainWindow): forum = Forum(id=-1, name="UNKNOWN") topics = [] forum_model = ForumModel() day_model = DayModel() def __init__(self): QMainWindow.__init__(self) self.date_view = QListView() self.forum_view = QListView() self.contentMax = 0 self.ioloop = asyncio.get_event_loop() icon = QIcon() icon.addPixmap(QPixmap(FAVICON_ICO), QIcon.Normal) self.setWindowIcon(icon) self.setWindowTitle(APP_TITLE) self.settings = QSettings('karoStudio', 'nnm-stats') self.resize(self.settings.value('main/size', QSize(640, 480))) self.move(self.settings.value('main/pos', QPoint(200, 200))) self.splitter = QSplitter() self.get_menu() self.content = QScrollArea() self.content.verticalScrollBar().valueChanged.connect( self.scrollBarChanged) self.content.verticalScrollBar().rangeChanged.connect( self.rangeChanged) self.torrents_list_view = QWidget() layout = QGridLayout() self.torrents_list_view.setLayout(layout) self.content.setWidget(self.torrents_list_view) self.splitter.addWidget(self.content) self.splitter.setSizes([160, 350]) self.setCentralWidget(self.splitter) self.timer = QTimer() self.timer.singleShot(1600, self.load_task) def get_menu(self): scroll = QScrollArea(self) self.forum_view.setStyleSheet("QListView{font: bold 12px;}") self.forum_view.clicked.connect(self.listViewClick) self.forum_view.setModel(self.forum_model) self.date_view.setStyleSheet("QListView{font: bold 12px;}") self.date_view.clicked.connect(self.listViewClick) self.date_view.setModel(self.day_model) menu_splitter = QSplitter(self) menu_splitter.setOrientation(Qt.Vertical) menu_splitter.addWidget(self.forum_view) menu_splitter.addWidget(self.date_view) scroll.setWidget(menu_splitter) scroll.setWidgetResizable(True) self.splitter.addWidget(scroll) def load_task(self): self.ioloop.run_until_complete(self.load_forums()) async def load_forums(self): tasks = [asyncio.ensure_future((get_forums("http://nnmclub.to/")))] done, pending = await asyncio.wait(tasks, return_when=FIRST_COMPLETED) forums = done.pop().result() for forum in forums: print(forum) self.forum_model.add(forum) def load_torrents_task(self, forum, start): self.ioloop.run_until_complete(self.load_torrents(forum, start)) async def load_torrents(self, forum, start=0): tasks = [asyncio.ensure_future((get_topics(forum, start)))] done, pending = await asyncio.wait(tasks, return_when=FIRST_COMPLETED) if start == 0: self.topics = done.pop().result() else: self.topics = self.topics + done.pop().result() layout = QGridLayout() self.topics.sort(key=lambda x: x.likes, reverse=True) days = {} for i, topic in enumerate(self.topics): d = topic.published.date() if d in days.keys(): days[d]['count'] += 1 days[d]['likes'] += topic.likes else: days[d] = {'count': 1, 'likes': topic.likes} # layout.addWidget(TopicView(topic), i, 0) for day in days.keys(): self.day_model.add(day, days[day]) self.torrents_list_view = QWidget() self.torrents_list_view.setLayout(layout) self.content.setWidget(self.torrents_list_view) def rangeChanged(self, vert_min, vert_max): self.contentMax = vert_max def scrollBarChanged(self, value): if value == self.contentMax: print("LOADING {}".format(self.torrents_list_view.children())) self.timer.singleShot( 1000, lambda: self.load_torrents_task(self.forum, len(self.topics))) def listViewClick(self, index): self.forum = self.forum_model.forums[index.row()] self.topics = [] self.setWindowTitle("{} / {}".format(APP_TITLE, self.forum.name)) self.day_model.clear() # self.timer.singleShot(1000, lambda: self.load_torrents_task(self.forum, 0)) self.timer.timeout.connect( lambda: self.load_torrents_task(self.forum, len(self.topics))) self.timer.start(8000) def closeEvent(self, event): self.settings.setValue('main/size', self.size()) self.settings.setValue('main/pos', self.pos()) self.ioloop.close()
class TabbedToolBox(QTabWidget): object_icon_clicked: SignalInstance = Signal(ObjectIcon) def __init__(self, parent=None): super(TabbedToolBox, self).__init__(parent) self.setTabPosition(self.East) self._recent_toolbox = ObjectToolBox(self) self._recent_toolbox.object_icon_clicked.connect(self.object_icon_clicked) self._recent_toolbox.object_placed.connect(self._on_object_dragged) self._objects_toolbox = ObjectToolBox(self) self._objects_toolbox.object_icon_clicked.connect(self.object_icon_clicked) self._objects_toolbox.object_placed.connect(self._on_object_dragged) self._enemies_toolbox = ObjectToolBox(self) self._enemies_toolbox.object_icon_clicked.connect(self.object_icon_clicked) self._enemies_toolbox.object_placed.connect(self._on_object_dragged) self._object_scroll_area = QScrollArea(self) self._object_scroll_area.setWidgetResizable(True) self._object_scroll_area.setWidget(self._objects_toolbox) self._enemies_scroll_area = QScrollArea(self) self._enemies_scroll_area.setWidgetResizable(True) self._enemies_scroll_area.setWidget(self._enemies_toolbox) self.addTab(self._recent_toolbox, "Recent") self.addTab(self._object_scroll_area, "Objects") self.addTab(self._enemies_scroll_area, "Enemies") self.show_level_object_tab() def sizeHint(self): size = super().sizeHint() width = self._recent_toolbox.sizeHint().width() width = max(width, self._objects_toolbox.sizeHint().width()) width = max(width, self._enemies_toolbox.sizeHint().width()) size.setWidth( max(width, size.width()) + self.tabBar().width() + self._object_scroll_area.verticalScrollBar().width() + 5 ) return size def show_recent_tab(self): self.setCurrentIndex(self.indexOf(self._recent_toolbox)) def show_level_object_tab(self): self.setCurrentIndex(self.indexOf(self._object_scroll_area)) def show_enemy_item_tab(self): self.setCurrentIndex(self.indexOf(self._enemies_scroll_area)) def select_object(self, level_object): recent_tab_showing = self.currentIndex() == self.indexOf(self._recent_toolbox) if self._recent_toolbox.has_object(level_object) and recent_tab_showing: pass elif isinstance(level_object, LevelObject): self.show_level_object_tab() elif isinstance(level_object, EnemyObject): self.show_enemy_item_tab() def set_object_set(self, object_set_index, graphic_set_index=-1): self._recent_toolbox.clear() self._objects_toolbox.clear() self._objects_toolbox.add_from_object_set(object_set_index, graphic_set_index) self._enemies_toolbox.clear() self._enemies_toolbox.add_from_enemy_set(object_set_index) def add_recent_object(self, level_object: Union[EnemyObject, LevelObject]): self._recent_toolbox.place_at_front(level_object) def _on_object_dragged(self, object_icon: ObjectIcon): self.add_recent_object(object_icon.object)
class Window(QWidget): def __init__(self): super().__init__() self.setWindowTitle('image-viewer') self.setGeometry(200, 200, 800, 600) self.image_path = 'F:\\browser-test\\test-dir\\4.jpg' self.cont_zoomed = None self.create_layout() self.show() def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_BracketLeft: self.zoom('in') event.accept() elif event.key() == QtCore.Qt.Key_BracketRight: self.zoom('out') event.accept() elif event.key() == QtCore.Qt.Key_Q: self.close() return super().keyPressEvent(event) def zoom(self, dire): if self.cont_zoomed: ratio = self.cont_zoomed else: ratio = self.content if dire == 'in': self.cont_zoomed = self.content.scaled(ratio.width() * 0.75, ratio.height() * 0.75, QtCore.Qt.KeepAspectRatio) elif dire == 'out': self.cont_zoomed = self.content.scaled(ratio.width() * 1.25, ratio.height() * 1.25, QtCore.Qt.KeepAspectRatio) self.image.setPixmap(self.cont_zoomed) def create_layout(self): self.image = QLabel() self.content = QPixmap(self.image_path) # FIXME: reset on resize self.image.setPixmap(self.content) self.label = QLabel() self.label.setText('image name probably') self.image_scroll = QScrollArea() self.image_scroll.setWidget(self.image) self.image_scroll.setAlignment(QtCore.Qt.AlignCenter) vbox = QVBoxLayout() vbox.addWidget(self.image_scroll) vbox.addWidget(self.label) # remove padding & margin vbox.setSpacing(0) vbox.setContentsMargins(0, 0, 0, 0) self.setLayout(vbox) def set_image(self, img): '''Change displayed image with the input from the main window. img -- path to image file ''' self.image_path = img self.content = QPixmap(self.image_path) self.image.setPixmap(self.content) self.label.setText(self.image_path) def resizeEvent(self, event): # increase image width in scroll area to fit into it self.image.setFixedWidth( self.width() - self.image_scroll.verticalScrollBar().width() - 2) return super().resizeEvent(event)
class Widget(QWidget): def __init__(self): QWidget.__init__(self) self.setWindowTitle("Backend Discord-GUI") self.changeStyle('fusion') palette = QPalette() palette.setColor(QPalette.Window, QColor(53, 53, 53)) palette.setColor(QPalette.WindowText, Qt.white) palette.setColor(QPalette.Text, Qt.white) palette.setColor(QPalette.Button, QColor(60, 60, 60)) palette.setColor(QPalette.ButtonText, Qt.white) palette.setColor(QPalette.Base, QColor(40, 40, 40)) palette.setColor(QPalette.ToolTipBase, QColor(60, 60, 60)) palette.setColor(QPalette.ToolTipText, Qt.white) palette.setColor(QPalette.PlaceholderText, Qt.white) palette.setColor(QPalette.BrightText, Qt.white) palette.setColor(QPalette.Highlight, QColor(106, 13, 173)) palette.setColor(QPalette.HighlightedText, Qt.white) topButtonLayout = QGroupBox("Configurations") topStatsLayout = QGroupBox("Statistics") layoutLeft = QHBoxLayout() botConfigButton = QPushButton("Bot Config") botConfigButton.clicked.connect(lambda: CommentPopup()) serverSettingsButton = QPushButton("Server Settings") settingsButton = QPushButton("Settings") layoutLeft.addWidget(botConfigButton) layoutLeft.addWidget(serverSettingsButton) layoutLeft.addWidget(settingsButton) layoutRight = QVBoxLayout() botReadyLabel = QLabel("Bot_Ready: False") botStatusLabel = QLabel("Bot_Status: Off") # botDatabaseLabel = QLabel("Bot_Database: None") # botStandbyLabel = QLabel("Bot_Standby: False") layoutRight.addWidget(botReadyLabel) layoutRight.addWidget(botStatusLabel) # layoutRight.addWidget(botDatabaseLabel) # layoutRight.addWidget(botStandbyLabel) topButtonLayout.setLayout(layoutLeft) topStatsLayout.setLayout(layoutRight) self.createLeftSide() self.createRightSide() self.createProgressBar() topLayout = QGridLayout() topLayout.addWidget(topButtonLayout, 0, 0) topLayout.addWidget(topStatsLayout, 0, 1) topLayout.setColumnStretch(0, 1) mainLayout = QGridLayout() mainLayout.addLayout(topLayout, 0, 0, 1, 2) mainLayout.addWidget(self.leftSideGB, 1, 0) mainLayout.addWidget(self.topRightGroupBox, 1, 1) mainLayout.addWidget(self.progressBar, 3, 0, 1, 2) mainLayout.setRowStretch(1, 2) mainLayout.setColumnStretch(0, 1) mainLayout.setColumnStretch(1, 2) self.setLayout(mainLayout) QApplication.setPalette(palette) def changeStyle(self, styleName): QApplication.setStyle(QStyleFactory.create(styleName)) def advanceProgressBarLoading(self): curVal = self.progressBar.value() maxVal = self.progressBar.maximum() if curVal != maxVal: num = random.randint(1, 30) self.progressBar.setValue(curVal + num) else: self.timer.stop() change_status('Ready') self.progressBar.setValue(0) def createLeftSide(self): self.leftSideGB = QGroupBox() home_directory = "./app/" palette = QPalette() palette.setColor(QPalette.Window, QColor(30, 30, 30)) model = QDirModel() view = QTreeView() view.setStyleSheet("QTreeView { border: 0px; }") view.setModel(model) view.setRootIndex(model.index(home_directory)) view.setColumnHidden(1, True) view.setColumnHidden(2, True) view.setColumnHidden(3, True) view.show() view.setPalette(palette) runButton = QPushButton("►") stopButton = QPushButton("❚❚") bottomBar = QHBoxLayout() bottomBar.addWidget(runButton) bottomBar.addWidget(stopButton) layout = QVBoxLayout() layout.addWidget(view) layout.addLayout(bottomBar) layout.setStretch(0, 2) self.leftSideGB.setLayout(layout) def createRightSide(self): self.topRightGroupBox = QGroupBox() self.totalLength = 0 self.elems = 0 self.elems_list = [] self.overall_layout = QVBoxLayout() grad = QPalette() gradient = QConicalGradient(QPointF(1100, 150), -190) gradient.setColorAt(0.0, QColor(30, 30, 30)) gradient.setColorAt(0.5, QColor(50, 50, 50)) gradient.setColorAt(0.97, QColor(50, 13, 150)) gradient.setColorAt(1.0, QColor(106, 13, 173)) gradient.setSpread(QGradient.RepeatSpread) grad.setBrush(QPalette.Window, QBrush(gradient)) self.setPalette(grad) self.scrollarea = QScrollArea() self.scrollarea.setWidgetResizable(True) self.widget = QWidget() self.scrollarea.setWidget(self.widget) self.layout = QVBoxLayout(self.widget) self.add_elem = QPushButton("Add Element") if PLATFORM == "darwin": self.add_elem.setToolTip("Shortcut: ⌘E") else: self.add_elem.setToolTip("Shortcut: Ctrl+E") self.add_elem.setStyleSheet( "QToolTip { border: 0px; border-radius: 3px }") self.add_elem.clicked.connect(lambda: ElementPopup()) self.add_elem.setFixedWidth(300) shortcut = QShortcut(QKeySequence("Ctrl+E"), self.add_elem) shortcut.activated.connect(lambda: ElementPopup()) shortcut.setEnabled(True) self.layout.addWidget(self.add_elem) self.layout.setAlignment(self.add_elem, Qt.AlignCenter | Qt.AlignTop) self.overall_layout.addWidget(self.scrollarea) self.topRightGroupBox.setLayout(self.overall_layout) def add_element(self, title, type, isDupe=False, indexForDupe=0, data=""): # open form of widget lists if data != "": title = title + ": " + data elem = create_elem(title, type, data) self.elems_list.append(elem.getElem()) self.elems += 1 self.totalLength += 100 if isDupe: self.layout.insertWidget(indexForDupe + 1, self.elems_list[self.elems - 1]) else: self.layout.insertWidget(self.elems - 1, self.elems_list[self.elems - 1]) if self.totalLength > self.topRightGroupBox.height(): self.scrollarea.verticalScrollBar().setMaximum( self.scrollarea.verticalScrollBar().maximum() + 85) self.scrollarea.verticalScrollBar().setValue( self.scrollarea.verticalScrollBar().maximum()) self.topRightGroupBox.update() def createProgressBar(self): self.progressBar = QProgressBar() self.progressBar.setRange(0, 10000) self.progressBar.setValue(0) self.progressBar.setTextVisible(False) self.progressBar.setFixedHeight(5) # self.timer = QTimer(self) # self.timer.timeout.connect(self.advanceProgressBarLoading) # self.timer.start(10) @Slot() def quit_application(self): QApplication.quit()
class TabbedToolBox(QTabWidget): object_icon_clicked: SignalInstance = Signal(ObjectIcon) def __init__(self, parent=None): super(TabbedToolBox, self).__init__(parent) self.setTabPosition(self.East) self._recent_toolbox = ObjectToolBox(self) self._recent_toolbox.object_icon_clicked.connect( self.object_icon_clicked) self._recent_toolbox.object_placed.connect(self._on_object_dragged) self._objects_toolbox = ObjectToolBox(self) self._objects_toolbox.object_icon_clicked.connect( self.object_icon_clicked) self._objects_toolbox.object_placed.connect(self._on_object_dragged) self._enemies_toolbox = ObjectToolBox(self) self._enemies_toolbox.object_icon_clicked.connect( self.object_icon_clicked) self._enemies_toolbox.object_placed.connect(self._on_object_dragged) self._object_scroll_area = QScrollArea(self) self._object_scroll_area.setWidgetResizable(True) self._object_scroll_area.setWidget(self._objects_toolbox) self._enemies_scroll_area = QScrollArea(self) self._enemies_scroll_area.setWidgetResizable(True) self._enemies_scroll_area.setWidget(self._enemies_toolbox) self.addTab(self._recent_toolbox, "Recent") self.addTab(self._object_scroll_area, "Objects") self.addTab(self._enemies_scroll_area, "Enemies") self.show_level_object_tab() self.setWhatsThis( "<b>Object Toolbox</b><br/>" "Contains all objects and enemies/items, that can be placed in this type of level. Which are " "available depends on the object set, that is selected for this level.<br/>" "You can drag and drop objects into the level or click to select them. After selecting " "an object, you can place it by clicking the middle mouse button anywhere in the level." "<br/><br/>" "Note: Some items, like blocks with items in them, are displayed as they appear in the ROM, " "mouse over them and check their names in the ToolTip, or use the object dropdown to find " "them directly.") def sizeHint(self): size = super().sizeHint() width = self._recent_toolbox.sizeHint().width() width = max(width, self._objects_toolbox.sizeHint().width()) width = max(width, self._enemies_toolbox.sizeHint().width()) size.setWidth( max(width, size.width()) + self.tabBar().width() + self._object_scroll_area.verticalScrollBar().width() + 5) return size def show_recent_tab(self): self.setCurrentIndex(self.indexOf(self._recent_toolbox)) def show_level_object_tab(self): self.setCurrentIndex(self.indexOf(self._object_scroll_area)) def show_enemy_item_tab(self): self.setCurrentIndex(self.indexOf(self._enemies_scroll_area)) def select_object(self, level_object): recent_tab_showing = self.currentIndex() == self.indexOf( self._recent_toolbox) if self._recent_toolbox.has_object( level_object) and recent_tab_showing: pass elif isinstance(level_object, LevelObject): self.show_level_object_tab() elif isinstance(level_object, EnemyObject): self.show_enemy_item_tab() def set_object_set(self, object_set_index, graphic_set_index=-1): self._recent_toolbox.clear() self._objects_toolbox.clear() self._objects_toolbox.add_from_object_set(object_set_index, graphic_set_index) self._enemies_toolbox.clear() self._enemies_toolbox.add_from_enemy_set(object_set_index) def add_recent_object(self, level_object: Union[EnemyObject, LevelObject]): self._recent_toolbox.place_at_front(level_object) def _on_object_dragged(self, object_icon: ObjectIcon): self.add_recent_object(object_icon.object)
class AudioSplitter(QWidget): def __init__(self): super(AudioSplitter, self).__init__() self.inputFile = '' self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) self.buildUI() def buildUI(self): self.closeButton = QPushButton('close') self.closeButton.setShortcut('Ctrl+W') self.closeButton.clicked.connect(self.onClose) self.closeButton.setFixedSize(0, 0) self.mainWrapperLayout = QVBoxLayout() self.mainWrapperLayout.addWidget(self.closeButton) self.divider1 = QFrame() self.divider1.setFrameShape(QFrame.HLine) self.divider1.setFrameShadow(QFrame.Sunken) self.divider2 = QFrame() self.divider2.setFrameShape(QFrame.HLine) self.divider2.setFrameShadow(QFrame.Sunken) self.headerLayout = self.buildHeader() self.optionsLayout = self.buildOptionsLayout() self.statusTextScroll = QScrollArea() self.statusTextScroll.setWidgetResizable(True) self.statusWidget = QWidget() self.statusTextScroll.setWidget(self.statusWidget) self.statusText = QVBoxLayout(self.statusWidget) self.statusTextScroll.setContentsMargins(0, 0, 0, 50) self.statusWidget.setLayout(self.statusText) self.mainWrapperLayout.addLayout(self.headerLayout) self.mainWrapperLayout.addWidget(self.divider1) self.mainWrapperLayout.addLayout(self.optionsLayout) self.mainWrapperLayout.addWidget(self.divider2) self.mainWrapperLayout.addWidget(self.statusTextScroll) self.startButton = QPushButton('Go') self.startButton.clicked.connect(self.onStartClick) self.mainWrapperLayout.addWidget(self.startButton) self.setLayout(self.mainWrapperLayout) self.setMinimumWidth(450) def buildHeader(self): appTitle = QLabel(self) appTitle.setText('Audio Splitter') appTitle.setFont(boldFont) chooseFileButton = QPushButton("Choose File") chooseFileButton.clicked.connect(self.loadNewFile) chooseFileButton.setShortcut('Ctrl+O') chooseFileButton.setMaximumWidth(90) self.fileLabel = QLabel() titleBar = QHBoxLayout() titleBar.addWidget(appTitle) titleBar.addWidget(chooseFileButton) headerLayout = QVBoxLayout() headerLayout.addLayout(titleBar) headerLayout.addWidget(self.fileLabel) return headerLayout def buildOptionsLayout(self): stemsRow = QHBoxLayout() stemsLabel = QLabel('Split into ') stemBox = QComboBox() stemBox.addItem('2 tracks') stemBox.addItem('4 tracks') stemBox.addItem('5 tracks') stemBox.setMaximumWidth(100) self.stemOptions = StemOptions() stemBox.activated[str].connect(self.stemOptions.setStems) stemsRow.addWidget(stemsLabel) stemsRow.addWidget(stemBox) stemsRow.addStretch() optionsLayout = QVBoxLayout() optionsLayout.addLayout(stemsRow) optionsLayout.addLayout(self.stemOptions) return optionsLayout def getCsvFileName(self): if "PYCHARM_HOSTED" in os.environ: success = \ QFileDialog.getOpenFileName(None, 'Open Audio Track', '', 'Audio Files (*.mp3 *.wav *.flac *.ogg)', options=QFileDialog.DontUseNativeDialog)[0] else: success = QFileDialog.getOpenFileName(None, 'Open Audio Track', '', 'Audio Files (*.mp3 *.wav *.flac *.ogg)')[0] if success: return success def loadNewFile(self): fileName = self.getCsvFileName() if fileName: path = Path(fileName) self.inputFile = path self.fileLabel.setText(f'Input: {self.inputFile.name}') def onStartClick(self): runInstance = RunSpleeter() self.updateStatus('Initializing') runInstance.startRun(self.inputFile, self.stemOptions.curStems, self.stemOptions.curOptions, self.updateStatus, self.saveOutput) def updateStatus(self, status, isError=False): newLine = QLabel(('ERROR' if isError else 'STATUS') + f': {status}') newLine.setWordWrap(True) self.statusText.addWidget(newLine) self.statusWidget.setLayout(self.statusText) QCoreApplication.processEvents() QCoreApplication.processEvents() self.statusTextScroll.verticalScrollBar().setValue(self.statusTextScroll.verticalScrollBar().maximum() + 1) def saveOutput(self): dlg = QFileDialog() if "PYCHARM_HOSTED" in os.environ: saveLoc = dlg.getSaveFileName(None, 'Save File', '', 'Zip files (*.zip)', options=QFileDialog.DontUseNativeDialog) else: saveLoc = dlg.getSaveFileName(None, 'Save File', '', 'Zip files (*.zip)') if saveLoc and saveLoc[0]: return saveLoc[0] def onClose(self): sys.exit()
class MainWindow(QWidget): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setWindowTitle('Commander V 0.1') self.resize(1600, 1200) #Functions self.commands = { # GUI commands 'CLEARALL': self.clear_all_results, # Basic Text Commands 'transform': TextFunctions().transform, '-tf': TextFunctions().transform, # Translation Commands 'translate': TextFunctions().translate, '-tr': TextFunctions().translate, # Information Commands 'extract': ExtractFunctions().extract, '-ext': ExtractFunctions().extract, 'regex': ExtractFunctions().regex, '-re': ExtractFunctions().regex, # Image Functions 'grayscale': ImageFunctions().grayscale, 'bw': ImageFunctions().bw, 'flip': ImageFunctions().flip, 'invert': ImageFunctions().invert } # Fonts self.text_font = QFont('monospace', 16) self.button_font = QFont('monospace', 18) self.console_font = QFont('monospace', 14) # Create widgets self.input_area = QTabWidget() self.input_area.setFont(self.text_font) self.text_area = QTextEdit() self.text_area.setFont(self.text_font) self.file_area = FileArea() self.image_area = ImageArea() self.result_scroll_area = QScrollArea() self.result_area = QWidget() self.result_area.layout = QVBoxLayout() self.result_area.setLayout(self.result_area.layout) self.result_scroll_area.setWidget(self.result_area) self.result_scroll_area.setWidgetResizable(True) self.console = QTextEdit() self.console.setMaximumHeight(300) self.console.setReadOnly(True) self.console.setStyleSheet( 'background-color: #0F0E0D; color: white; border: 0;') self.console.setFont(self.console_font) def set_command_line_focus(event): self.command_line.setFocus() self.console.mousePressEvent = set_command_line_focus self.command_line = QLineEdit() # self.command_line.setStyleSheet('background-color: #0F0E0D; color: white; border: 0;') self.command_line.setFont(self.console_font) self.command_line.setPlaceholderText('Enter command') self.command_line.setTextMargins(5, 0, 0, 0) self.execute_button = QPushButton("Execute") self.execute_button.setFont(self.button_font) self.execute_button.setStyleSheet( 'background-color: red; color: white;') self.command_line.returnPressed.connect(self.execute_button.click) self.execute_button.setVisible(False) # Create layout and add widgets self.layout = QGridLayout() self.top_layout = QGridLayout() # Tabbed input area self.top_layout.addWidget(self.input_area, 0, 0) self.input_area.insertTab(0, self.text_area, 'Text') self.input_area.insertTab(1, self.file_area, 'File') self.input_area.insertTab(2, self.image_area, 'Image') self.top_layout.addWidget(self.result_scroll_area, 0, 2) self.bottom_layout = QGridLayout() self.bottom_layout.setSpacing(0) self.bottom_layout.addWidget(self.console, 0, 0) self.bottom_layout.addWidget(self.command_line, 1, 0) self.bottom_layout.addWidget(self.execute_button, 2, 0) # Set layout self.setLayout(self.layout) self.layout.addLayout(self.top_layout, 0, 0) self.layout.addLayout(self.bottom_layout, 1, 0) # Add button signal to execution function self.execute_button.clicked.connect(self.execute_command) # Set focus to command line self.command_line.setFocus() def clear_all_results(self, *args, **kwargs): for i in reversed(range(self.result_area.layout.count())): self.result_area.layout.itemAt(i).widget().setParent(None) # Executes command def execute_command(self): command = self.command_line.text().split(' ') command_action = command[0] if len(command) == 1: command_arguments = [] else: command_arguments = ' '.join(command[1:]) if self.input_area.currentIndex() == 0: data_input = self.text_area elif self.input_area.currentIndex() == 1: data_input = self.file_area.file_preview elif self.input_area.currentIndex() == 2: data_input = self.image_area.selected_file_name.text() # Data Types: if self.input_area.currentIndex() == 0 or self.input_area.currentIndex( ) == 1: plain_data = data_input.toPlainText() html_data = data_input.toHtml() markdown_data = data_input.toMarkdown() data = { 'plain': plain_data, 'html': html_data, 'markdown': markdown_data } elif self.input_area.currentIndex() == 2: image_data = data_input data = {'image': image_data} if command_action in self.commands: function = self.commands[command_action] result = function(data, command_arguments) # Check to see if function returns a result, then sets variables if result: result_output = result['output'] result_data_type = result['type'] result_console_message = result['console_message'] command_print = QLineEdit(self.command_line.text()) command_print.setFont(self.console_font) command_print.setReadOnly(True) # Clears command line self.command_line.clear() # Inserts the command and the result as widgets if result_output: self.result_area.layout.addWidget(command_print) result_block = ResultBlock(result_output, result_data_type) self.result_area.layout.addWidget(result_block) # Make sure scrollbar is always at the bottom scroll_bar = self.result_scroll_area.verticalScrollBar() scroll_bar.rangeChanged.connect( lambda x, y: scroll_bar.setValue(y)) # Inserts console_message to console if result_console_message: self.console.append(result['console_message'])
class MyWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.thread = SerialMonitorThread() self.thread.dataReady.connect(self.get_data, Qt.QueuedConnection) self.thread.setTerminationEnabled(True) #Menu self.setPalette(get_verifone_color()) collapsible = CollapsibleWidget() self.init_logging(collapsible) self.init_download(collapsible) self.init_analyser(collapsible) collapsible.add_sections() # Scroll Area self.createLoggingDisplayLabel() self.scrollArea = QScrollArea() self.scrollArea.setBackgroundRole(QPalette.Dark) self.scrollArea.setWidget(self.text) self.scrollArea.setWidgetResizable(True) hLayout = QHBoxLayout() #hLayout.addLayout(vLayout) hLayout.addWidget(collapsible) hLayout.addWidget(self.scrollArea) self.setLayout(hLayout) def init_logging(self, collapsible): self.logger = QPushButton("Start Logging", self) self.logger.setFont(QFont("Times", 14, QFont.Bold)) self.logger.clicked.connect(lambda: self.display_log_data()) self.logger.setStyleSheet("background-color: white") #self.filterLayout = QtWidgets.QHBoxLayout() self.logFilterLabel = QLabel('Filter', self) self.logFilterLabel.setFont(QFont("Times", 14, QFont.Bold)) self.logFilterLabel.setPalette(get_white_color_text()) self.logFilterLabel.setFixedWidth(60) self.logFilter = QLineEdit(self) self.logFilter.setPalette(get_white_color()) self.logFilter.setStyleSheet("background-color: white") self.logFilter.setFixedWidth(200) #self.filterLayout.addWidget(self.logFilterLabel, QtCore.Qt.AlignLeft) #self.filterLayout.addWidget(self.logFilter, QtCore.Qt.AlignLeft) self.serialList = QComboBox() ports = get_available_serial_ports() if (len(ports) == 1): self.serialList.addItem(ports[0]) self.thread.set_comport(self.serialList.currentText()) else: self.serialList.addItem("Select") for port in ports: self.serialList.addItem(port) self.serialList.currentIndexChanged.connect( lambda: self.set_serial_port()) self.serialList.setStyleSheet("background-color: white") self.clear = QPushButton("Clear Log File", self) self.clear.setStyleSheet("background-color: white") self.clear.setFont(QFont("Times", 14, QFont.Bold)) self.clear.clicked.connect(lambda: self.clear_data()) widget = QFrame(collapsible.get_tree()) widget.setPalette(get_verifone_color()) title = "Logging" self.loggerGrid = QGridLayout(widget) self.loggerGrid.addWidget(self.logger, 0, 0, 1, 2) self.loggerGrid.addWidget(self.logFilterLabel, 1, 0, 1, 1) self.loggerGrid.addWidget(self.logFilter, 1, 1, 1, 1) self.loggerGrid.addWidget(self.serialList, 2, 0, 1, 2) self.loggerGrid.addWidget(self.clear, 3, 0, 1, 2) collapsible.include_section(title, widget) def init_download(self, collapsible): self.download = QPushButton("Download Package", self) self.download.setFont(QFont("Times", 14, QFont.Bold)) self.download.clicked.connect(lambda: self.send_file()) self.download.setStyleSheet("background-color: white") self.loadDownloadFile = QPushButton("Load File", self) self.loadDownloadFile.setFont(QFont("Times", 14, QFont.Bold)) self.loadDownloadFile.clicked.connect(self.loadFromFile) self.loadDownloadFile.setStyleSheet("background-color: white") self.downloadFileName = QLineEdit("File name", self) self.downloadFileName.setStyleSheet("background-color: white") self.downloadFileName.setFixedWidth(300) self.downloadAddress = QLineEdit("IP Address", self) self.downloadAddress.setStyleSheet("background-color: white") self.downloadAddress.setFixedWidth(300) self.downloadStatus = QLabel("Download Status", self) self.downloadStatus.setStyleSheet( "background-color: rgba(3, 169, 229, 0); color : white") self.downloadStatus.setFixedWidth(300) widget = QFrame(collapsible.get_tree()) title = "Download" self.downloadGrid = QGridLayout(widget) self.downloadGrid.addWidget(self.download, 0, 0, 1, 2) self.downloadGrid.addWidget(self.loadDownloadFile, 1, 0, 1, 2) self.downloadGrid.addWidget(self.downloadFileName, 2, 0, 1, 2) self.downloadGrid.addWidget(self.downloadAddress, 3, 0, 1, 2) self.downloadGrid.addWidget(self.downloadStatus, 4, 0, 1, 2) collapsible.include_section(title, widget) def init_analyser(self, collapsible): self.performanceData = QPushButton("View Performance Data", self) self.performanceData.setFont(QFont("Times", 14, QFont.Bold)) self.performanceData.clicked.connect( lambda: self.display_performance_data()) self.performanceData.setStyleSheet("background-color: white") self.performanceChart = QPushButton("View Performance Chart", self) self.performanceChart.setFont(QFont("Times", 14, QFont.Bold)) self.performanceChart.clicked.connect( lambda: self.display_performance_chart()) self.performanceChart.setStyleSheet("background-color: white") widget = QFrame(collapsible.get_tree()) title = "Analyser" self.analyserGrid = QGridLayout(widget) self.analyserGrid.addWidget(self.performanceData, 0, 0, 1, 2) self.analyserGrid.addWidget(self.performanceChart, 1, 0, 1, 2) collapsible.include_section(title, widget) def loadFromFile(self): fileName, _ = QFileDialog.getOpenFileName( self, "Load Package", '', "Download Files (*.tgz);;All Files (*)") if not fileName: return try: in_file = open(str(fileName), 'rb') except IOError: QMessageBox.information( self, "Unable to open file", "There was an error opening \"%s\"" % fileName) return in_file.close() self.downloadFileName.setText(fileName) def createLoggingDisplayLabel(self): # Display Area self.text = QPlainTextEdit(self) self.text.setReadOnly(True) self.text.setFont(QFont("Times", 12, QFont.Bold)) self.text.setTextInteractionFlags(Qt.TextSelectableByMouse | Qt.TextSelectableByKeyboard) def clear_data(self): self.text.clear() os.remove(logfile_path, dir_fd=None) def display_log_data(self): #send_file() if ('COM' in self.serialList.currentText()): self.createLoggingDisplayLabel() self.scrollArea.setWidget(self.text) self.thread.stop() self.thread.start() data = get_data_from_file(logfile_path) if (len(data) > 0 and data != None): self.text.appendPlainText(data) self.logger.setDisabled(True) def get_data(self, data): if (len(data) > 0): logFile = open(logfile_path, "a") logFile.write(data) logFile.close() filterText = self.logFilter.text() if filterText in data.rstrip(): self.text.appendPlainText(data.rstrip()) vbar = self.scrollArea.verticalScrollBar() vbar.setValue(vbar.maximum()) def display_performance_data(self): self.thread.stop() data = get_data_from_file(logfile_path) jsonData = translate_data_to_json(data) self.performanceData = DisplayPerformanceData() self.performanceData.loadCsv( os.path.join(base_log_path, "performance_data.csv")) self.scrollArea.setWidget(self.performanceData) self.logger.setDisabled(False) def display_performance_chart(self): self.thread.stop() self.scrollArea.setWidget(get_performace_chart()) self.logger.setDisabled(False) def set_serial_port(self): self.thread.set_comport(self.serialList.currentText()) def send_file(self): base_path = os.path.join("c:/", "VFI", 'wks', 'global-payment-application', 'GPA', 'output', 'vos2', 'gpa', 'dl.gpa-1.0.0.0-000.tgz') fileName = self.downloadFileName.text() try: in_file = open(str(fileName), 'rb') except IOError: QMessageBox.information( self, "Unable to open file", "There was an error opening \"%s\"" % fileName) return in_file.close() load_vos_package_ip('192.168.0.104', fileName, self.downloadStatus)