def _load_ui(self): main_layout = QVBoxLayout(self) main_layout.addWidget(QLabel(translations.TR_SESSIONS_DIALOG_BODY)) main_hbox = QHBoxLayout() # Session list session_layout = QVBoxLayout() self._session_list = QTreeWidget() self._session_list.setHeaderLabels(["Session", "Last Modified"]) session_layout.addWidget(self._session_list) # Content frame content_frame = QFrame() content_frame.hide() frame_layout = QVBoxLayout(content_frame) content_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) session_layout.addWidget(content_frame) frame_layout.setContentsMargins(0, 0, 0, 0) self._content_list = QTreeWidget() self._content_list.setHeaderHidden(True) frame_layout.addWidget(self._content_list) # Separator line line_frame = QFrame() line_frame.setFrameStyle(QFrame.VLine | QFrame.Sunken) # Buttons btn_layout = QVBoxLayout() btn_create = QPushButton(translations.TR_SESSIONS_BTN_CREATE) btn_activate = QPushButton(translations.TR_SESSIONS_BTN_ACTIVATE) btn_update = QPushButton(translations.TR_SESSIONS_BTN_UPDATE) btn_delete = QPushButton(translations.TR_SESSIONS_BTN_DELETE) btn_details = QPushButton(translations.TR_SESSIONS_BTN_DETAILS) btn_details.setCheckable(True) # Add buttons to layout btn_layout.addWidget(btn_create) btn_layout.addWidget(btn_activate) btn_layout.addWidget(btn_update) btn_layout.addWidget(btn_delete) btn_layout.addStretch() btn_layout.addWidget(btn_details) # Add widgets and layouts to the main layout main_layout.addLayout(main_hbox) main_hbox.addLayout(session_layout) main_hbox.addWidget(line_frame) main_hbox.addLayout(btn_layout) main_hbox.setSizeConstraint(QLayout.SetFixedSize) btn_details.toggled[bool].connect(content_frame.setVisible) # Connections self._session_list.itemSelectionChanged.connect( self.load_session_content) btn_activate.clicked.connect(self.open_session) btn_update.clicked.connect(self.save_session) btn_create.clicked.connect(self.create_session) btn_delete.clicked.connect(self.delete_session)
class StockSourceDisplayPanel: def __init__(self,parent,world): self.parent = parent self.world = world self.scrollable_display = 0 self.button_display = 0 self.button_list = [] self.initUI() def initUI(self): self.scrollable_display = QScrollArea(self.parent) self.button_display = QFrame(self.scrollable_display) self.scrollable_display.setWidget(self.button_display) self.populate_button_list() self.scrollable_display.show() self.button_display.show() def populate_button_list(self): stock_list = self.world.get_stock_source_list() vbox = QVBoxLayout() button_list = [] i = 0 for entry in stock_list: entry_button = QPushButton(entry.get_name()) button_list.append(entry_button) vbox.addWidget(entry_button) entry_button.clicked.connect(functools.partial(self.parent.stockUI,i,stock_target=entry.get_stock())) i += 1 vbox.addStretch(1) self.button_display.setLayout(vbox) self.resize() def destroy(self): self.scrollable_display.hide() self.button_display.hide() self.parent.resize(self.parent.size()) self.button_display.destroy(False, False) self.scrollable_display.destroy(False, False) def resize(self): self.scrollable_display.resize(self.parent.size()) frameWidth = self.scrollable_display.lineWidth() self.button_display.resize(self.scrollable_display.size().width()-(frameWidth*2),self.scrollable_display.size().height()-(frameWidth*2))
def createBox(self): box = QFrame(self) #box.setMinimumSize(self.width(), self.height()/3) box.setMaximumSize(self.width(), self.height() / 3) box.setStyleSheet("background-color:yellow") box.setAutoFillBackground(True) box.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) box.setStyleSheet("background-color:#f5f5ef") box.setFrameShape(QFrame.Box) font = QFont("Times new roman", 15) layout = QVBoxLayout(box) layout.setContentsMargins(5, 0, 0, 5) date = QLabel('', box) date.setObjectName('date') date.setFont(font) date.setStyleSheet("font-weight: bold;") name = QLabel('', box) name.setObjectName('name') name.setFont(font) layout.addWidget(date) layout.addWidget(name) layout.setAlignment(date, Qt.AlignTop) layout.setAlignment(name, Qt.AlignBottom) box.setLayout(layout) self.layout.addWidget(box) #layout.setAlignment(box,Qt.AlignTop) box.hide() return box
class MapView(QFrame): def __init__(self, parent): super(MapView, self).__init__(parent) self.parent = parent self.initUI(self.parent.gameboard) self.mouse_x = 0 self.mouse_y = 0 self.clickedTower = None def initUI(self, gameboard): self.setFixedSize((gameboard.width - 1)*blockSize, gameboard.height*blockSize) self.setMouseTracking(True) self.show() def paintEvent(self, event): qp = QPainter() qp.begin(self) self.drawMap(qp) if self.underMouse() and self.parent.isTowerSelected: # Draws the tower outline and range of the tower being build self.drawTowerRange(self.mouse_x, self.mouse_y, self.parent.selectedTower.range, qp) self.drawTowerOutline(self.mouse_x, self.mouse_y, qp) if not self.parent.isTowerSelected and self.parent.isTowerHovered: # Draws tower range when a tower is being hovered self.drawTowerRange(self.parent.towerBeingHovered.posX, self.parent.towerBeingHovered.posY, self.parent.towerBeingHovered.range, qp) self.drawPorjectiles(qp) qp.end() def drawMap(self, qp): self.drawMapBlocks(qp, self.parent.gameboard.river, riverColor) self.drawMapBlocks(qp, self.parent.gameboard.road, roadColor) self.drawMapBlocks(qp, self.parent.gameboard.unoccupied, grassColor) self.drawMapBlocks(qp, self.parent.gameboard.cave, caveColor) self.drawMapBlocks(qp, self.parent.gameboard.mountain, mountainColor) self.drawMapBlocks(qp, self.parent.gameboard.bridge, woodColor) def drawMapBlocks(self, qp, coordinateList, color): # Draws map blocks according to the coordinate list qp.setPen(gridColor) qp.setBrush(color) for i in coordinateList: qp.drawRect(i[0]*blockSize, i[1]*blockSize, blockSize, blockSize) def drawTowerRange(self, x, y, towerRange, painter): painter.setPen(rangePenColor) painter.setBrush(rangeBrushColor) painter.drawEllipse(QPoint(x, y), towerRange, towerRange) def drawTowerOutline(self, x, y, painter): painter.setPen(rangePenColor) painter.setBrush(rangeBrushColor) painter.drawRect(x - 20, y - 20, 40, 40) def drawPorjectiles(self, qp): qp.setPen(projectileColor) qp.setBrush(projectileColor) for projectile in self.parent.gameboard.projectiles: if not projectile.isFinished: if projectile.name == "Bullet": qp.drawEllipse(projectile.posX, projectile.posY, 3, 3) elif projectile.name == "Cannonball": qp.drawEllipse(projectile.posX, projectile.posY, 8, 8) def mouseMoveEvent(self, event): # This method makes sure that towers are build according to the grid and that the tower outline and range are displayed properly if self.underMouse() and self.parent.isTowerSelected == True: self.mouse_x, self.mouse_y = self.calculateClosestCorner(event.pos().x(), event.pos().y()) def calculateClosestCorner(self, mouse_x, mouse_y): # Calculates the closest grid corner from mouse location closest_corner_x = 0 closest_corner_y = 0 if mouse_x % blockSize < blockSize / 2: closest_corner_x = mouse_x - (mouse_x % blockSize) else: closest_corner_x = mouse_x + (blockSize - mouse_x % blockSize) if mouse_y % blockSize < blockSize / 2: closest_corner_y = mouse_y - (mouse_y % blockSize) else: closest_corner_y = mouse_y + (blockSize - mouse_y % blockSize) return closest_corner_x, closest_corner_y def mousePressEvent(self, e): # Method for building towers and checking that their location is ok if e.button() == Qt.LeftButton: if self.parent.gameover == False: if self.parent.isTowerSelected == True: # We calculate the bottom right block for the tower block1 = [int(self.mouse_x / blockSize), int(self.mouse_y / blockSize)] # We need to make sure that the tower doesn't go over the borders of the gameboard if block1[0] > 0 and block1[1] > 0 and block1[0] < self.parent.gameboard.width and block1[1] < self.parent.gameboard.height: #Then we calculate the other blocks block2 = [block1[0] - 1, block1[1]] block3 = [block1[0] - 1, block1[1] - 1] block4 = [block1[0], block1[1] - 1] blocks = [block1, block2, block3, block4] occupied = self.parent.gameboard.occupied canPlaceTower = True # We check that none of the tower blocks are occupied for block in blocks: if block in occupied: canPlaceTower = False if canPlaceTower == True: # We places the tower on the map tower = self.parent.selectedTower tower.setPosition(self.mouse_x, self.mouse_y) placedTower = ClickableTower(tower, self) placedTower.move(block3[0] * blockSize, block3[1] * blockSize) placedTower.show() # Then we add the tower blocks to the list of occupied tiles for block in blocks: self.parent.gameboard.addToOccupied(block) self.parent.gameboard.addBuildTower(tower) self.parent.gameboard.buy(tower.price) self.parent.gamestats.update() self.statusBarMessage('Tower build') self.parent.selectedTower = None self.parent.isTowerSelected = False else: self.statusBarMessage("Can't place it there!") else: self.statusBarMessage("Can't place it there!") else: self.statusBarMessage("The game has ended. You can't build towers.") else: # If we click the right mouse button we cancel the tower selection self.parent.selectedTower = None self.parent.isTowerSelected = False self.statusBarMessage('') self.update() def getParent(self): # Not sure if I'm using this anywhere return self.parent def statusBarMessage(self, message): # Just a shorter way to write statusbar messages self.parent.statusBar().showMessage(message) def towerClick(self, tower): # Opens a popup to see tower stats and to upgrade tower if self.parent.gameover == False: if self.parent.isTowerSelected == False: self.clickedTower = tower # self.statusBarMessage("Tower clicked") self.towerPopUp = QFrame() self.towerPopUp.setGeometry(500, 500, 100, 100) grid = QGridLayout() self.towerPopUp.setLayout(grid) vbox = QVBoxLayout() pixmap = QLabel() vbox.addStretch() if tower.level == 2: pixmap.setPixmap(tower.upgradedPicture) else: pixmap.setPixmap(tower.picture) vbox.addWidget(pixmap) vbox.addStretch() grid.addLayout(vbox, 0, 0) towerStats = QLabel(tower.name + " Tower Stats", self) power = QLabel("Power: {:.0f}".format(tower.power), self) towerRange = QLabel("Range: {:.0f}".format(tower.range), self) fireRate = QLabel("Rate of Fire: " + str(tower.fireRate), self) level = QLabel("Level: " + str(tower.level), self) vbox2 = QVBoxLayout() vbox2.addWidget(towerStats) vbox2.addWidget(power) vbox2.addWidget(towerRange) vbox2.addWidget(fireRate) vbox2.addWidget(level) grid.addLayout(vbox2, 0, 1) vbox3 = QVBoxLayout() if self.clickedTower.maxLevel > self.clickedTower.level: upgradeButton = QPushButton("Upgrade for " + str(tower.upgradePrice)) vbox3.addWidget(upgradeButton) upgradeButton.clicked.connect(self.upgrade) else: maxLevel = QLabel("Tower at maximum level.") vbox3.addWidget(maxLevel) doneButton = QPushButton("Done") vbox3.addWidget(doneButton) grid.addLayout(vbox3, 0, 2) location = QPoint(QCursor.pos()) self.towerPopUp.move(location.x() - 180, location.y()) self.towerPopUp.show() doneButton.clicked.connect(self.towerPopUp.hide) else: self.statusBarMessage("The game has ended. Stop doing stuff.") def upgrade(self): if self.clickedTower.level < self.clickedTower.maxLevel: if self.parent.gameboard.money >= self.clickedTower.upgradePrice: self.clickedTower.upgrade() self.parent.gameboard.buy(self.clickedTower.upgradePrice) self.statusBarMessage("Tower upgraded") self.parent.gamestats.update() self.towerPopUp.hide() else: self.statusBarMessage("Not enough money to upgrade.") else: self.statusBarMessage("Tower already at maximum level.") def summonEnemy(self): # Summons an enemy at given intervals waveIndex = self.parent.gameboard.currentWave - 1 if self.parent.gameboard.currentWave <= len(self.parent.gameboard.waves): # self.parent.gameboard.waves[waveIndex][0] gives the enemy interval for that wave if self.parent.gameboard.currentEnemy == 1: # This makes sure that there's a break between enemy waves, the length of the break can be defined in globals if self.parent.timePassed - self.parent.waveFinishTime >= breakBetweenWaves: if self.checkNextEnemy("e1", Barbarian(self.parent.gameboard.enemyPath, self)): self.checkIsWaveDone() elif self.checkNextEnemy("e2", Berserker(self.parent.gameboard.enemyPath, self)): self.checkIsWaveDone() elif self.parent.timePassed % self.parent.gameboard.waves[waveIndex][0] == 0: if self.checkNextEnemy("e1", Barbarian(self.parent.gameboard.enemyPath, self)): self.checkIsWaveDone() elif self.checkNextEnemy("e2", Berserker(self.parent.gameboard.enemyPath, self)): self.checkIsWaveDone() def checkIsWaveDone(self): waveIndex = self.parent.gameboard.currentWave - 1 if self.parent.gameboard.currentEnemy > len(self.parent.gameboard.waves[waveIndex][1]): self.parent.gameboard.currentEnemy = 1 self.parent.gameboard.currentWave += 1 self.parent.waveFinishTime = self.parent.timePassed self.parent.gamestats.update() return True else: return False def checkNextEnemy(self, name, enemyType): # This method could probably be changed a bit, but it does it's job. I'll update it if I have time. enemyIndex = self.parent.gameboard.currentEnemy - 1 waveIndex = self.parent.gameboard.currentWave - 1 if self.parent.gameboard.waves[waveIndex][1][enemyIndex] == name: enemy = enemyType enemy.move(enemy.posX, enemy.posY) enemy.show() self.parent.gameboard.addSummonedEnemy(enemy) self.parent.gameboard.currentEnemy += 1 return True else: return False def moveEnemies(self): noOfSummonedEnemies = len(self.parent.gameboard.enemiesSummoned) if noOfSummonedEnemies > 0: i = 0 while i < noOfSummonedEnemies: enemy = self.parent.gameboard.enemiesSummoned[i] if not enemy.isFinished and not enemy.isDead: enemy.moveEnemy() if enemy.checkIfFinished(): self.parent.gameboard.currentLives -= 1 self.parent.update() if self.parent.gameboard.currentLives <= 0: self.parent.loseGame() else: self.checkIfGameEnded() i += 1 def enemyClick(self, enemy): # Opens an info screen on the enemy if self.parent.gameover == False and enemy.isDead == False: if self.parent.isTowerSelected == False: # self.statusBarMessage("Enemy clicked") self.enemyPopUp = QFrame() self.enemyPopUp.setGeometry(500, 500, 100, 100) grid = QGridLayout() self.enemyPopUp.setLayout(grid) enemyStats = QLabel("Enemy Stats") name = QLabel("Name: " + str(enemy.name)) speed = QLabel("Speed: " + str(enemy.speed)) health = QLabel("Health: {:.0f}".format(enemy.health)) pixmap = QLabel() pixmap.setPixmap(enemy.picture) vbox = QVBoxLayout() vbox.addWidget(enemyStats) vbox.addWidget(name) vbox.addWidget(speed) vbox.addWidget(health) grid.addLayout(vbox, 0, 0) vbox2 = QVBoxLayout() vbox2.addWidget(pixmap) vbox2.addStretch() doneButton = QPushButton("Done") vbox2.addWidget(doneButton) grid.addLayout(vbox2, 0, 1) location = QPoint(QCursor.pos()) self.enemyPopUp.move(location.x() - 100, location.y()) self.enemyPopUp.show() doneButton.clicked.connect(self.enemyPopUp.hide) elif self.parent.gameover == True: self.statusBarMessage("The game has ended. Stop doing stuff.") def checkShooting(self): # We go trough the towers we have build and check if they have enemies in range for tower in self.parent.gameboard.towersBuild: # This is kind of a simple method of checking the firerate # We firs check when the tower has fired it's last shot to see if it's time to shoot again if tower.lastShot == 0 or self.parent.timePassed - tower.lastShot >= tower.fireRate: # We always shoot the enemy that has moved to the furthest block. If there's more than one enemy in the same block we select the one that's first in the list. # Again, this method could be improved. We could check which enemy is actually furthest down the path in actual pixels. i = 0 maxBlocks = -1 targetEnemy = None while i < len(self.parent.gameboard.enemiesSummoned): enemy = self.parent.gameboard.enemiesSummoned[i] # We shouldn't shoot enemies that are dead or have already reached the end of the path. if enemy.isFinished == False and enemy.isDead == False: if tower.inRange(enemy): if enemy.blocksMoved > maxBlocks: maxBlocks = enemy.blocksMoved targetEnemy = enemy i += 1 if targetEnemy != None: projectile = tower.shoot(targetEnemy) tower.lastShot = self.parent.timePassed self.parent.gameboard.addProjectile(projectile) # self.statusBarMessage(tower.name + " shoots " + targetEnemy.name + " with " + projectile.name) def moveProjectiles(self): for projectile in self.parent.gameboard.projectiles: if not projectile.isFinished: projectile.move() if projectile.checkIfHit(): # self.statusBarMessage(projectile.destination.name + " takes a hit of " + str(projectile.damage) + " damage.") if projectile.name == "Cannonball": # Cannonballs damage all enemies in the same block. # This method could also be improved. We should probably hit enemies that are within a certain range from the target enemy instead of being in the same block. for enemy in self.parent.gameboard.enemiesSummoned: if enemy != projectile.destination and enemy.currentBlock == projectile.destination.currentBlock: if enemy.getHit(projectile.damage): enemy.checkIfDead() if projectile.destination.checkIfDead(): # self.statusBarMessage(projectile.destination.name + " is dead. You get " + str(projectile.destination.reward) + " coins.") self.parent.gameboard.addMoney(projectile.destination.reward) self.parent.gamestats.update() self.checkIfGameEnded() def checkIfGameEnded(self): # This method checks if all waves have been sent and all summoned enemies have either reached their destination or died. allDone = False if self.parent.gameboard.currentWave >= len(self.parent.gameboard.waves): # self.statusBarMessage("Last wave!") # Check how many enemies the map has in total. This should probably be an attribute that's calculated already when the GameBoard-object is made. totalEnemies = 0 for wave in self.parent.gameboard.waves: totalEnemies += len(wave[1]) # Then we compare that number to the number of summoned enemies if len(self.parent.gameboard.enemiesSummoned) == totalEnemies: # self.statusBarMessage("All enemies summoned!") allDone = True # Then we check if they are all dead or finished for enemy in self.parent.gameboard.enemiesSummoned: if enemy.isFinished == False and enemy.isDead == False: allDone = False # If so the game has ended and the player is victorious if allDone: self.parent.winGame()
class VideoFinderAddLink(AddLinkWindow): running_thread = None threadPool = {} def __init__(self, parent, receiver_slot, settings, video_dict={}): super().__init__(parent, receiver_slot, settings, video_dict) self.setWindowTitle( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Video Finder')) self.size_label.hide() # empty lists for no_audio and no_video and video_audio files self.no_audio_list = [] self.no_video_list = [] self.video_audio_list = [] self.media_title = '' # add support for other languages locale = str(self.persepolis_setting.value('settings/locale')) QLocale.setDefault(QLocale(locale)) self.translator = QTranslator() if self.translator.load(':/translations/locales/ui_' + locale, 'ts'): QCoreApplication.installTranslator(self.translator) # extension_label self.extension_label = QLabel(self.link_frame) self.change_name_horizontalLayout.addWidget(self.extension_label) # Fetch Button self.url_submit_pushButtontton = QPushButton(self.link_frame) self.link_horizontalLayout.addWidget(self.url_submit_pushButtontton) # Status Box self.status_box_textEdit = QTextEdit(self.link_frame) self.status_box_textEdit.setMaximumHeight(150) self.link_verticalLayout.addWidget(self.status_box_textEdit) # Select format horizontal layout select_format_horizontalLayout = QHBoxLayout() # Selection Label select_format_label = QLabel(self.link_frame) select_format_horizontalLayout.addWidget(select_format_label) # Selection combobox self.media_comboBox = QComboBox(self.link_frame) self.media_comboBox.setMinimumWidth(200) select_format_horizontalLayout.addWidget(self.media_comboBox) # Duration label self.duration_label = QLabel(self.link_frame) select_format_horizontalLayout.addWidget(self.duration_label) self.format_selection_frame = QFrame(self) self.format_selection_frame.setLayout(select_format_horizontalLayout) self.link_verticalLayout.addWidget(self.format_selection_frame) # advanced_format_selection_checkBox self.advanced_format_selection_checkBox = QCheckBox(self) self.link_verticalLayout.addWidget( self.advanced_format_selection_checkBox) # advanced_format_selection_frame self.advanced_format_selection_frame = QFrame(self) self.link_verticalLayout.addWidget( self.advanced_format_selection_frame) advanced_format_selection_horizontalLayout = QHBoxLayout( self.advanced_format_selection_frame) # video_format_selection self.video_format_selection_label = QLabel( self.advanced_format_selection_frame) self.video_format_selection_comboBox = QComboBox( self.advanced_format_selection_frame) # audio_format_selection self.audio_format_selection_label = QLabel( self.advanced_format_selection_frame) self.audio_format_selection_comboBox = QComboBox( self.advanced_format_selection_frame) for widget in [ self.video_format_selection_label, self.video_format_selection_comboBox, self.audio_format_selection_label, self.audio_format_selection_comboBox ]: advanced_format_selection_horizontalLayout.addWidget(widget) # Set Texts self.url_submit_pushButtontton.setText( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Fetch Media List')) select_format_label.setText( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Select a format')) self.video_format_selection_label.setText( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Video format:')) self.audio_format_selection_label.setText( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Audio format:')) self.advanced_format_selection_checkBox.setText( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Advanced options')) # Add Slot Connections self.url_submit_pushButtontton.setEnabled(False) self.change_name_lineEdit.setEnabled(False) self.ok_pushButton.setEnabled(False) self.download_later_pushButton.setEnabled(False) self.format_selection_frame.setEnabled(True) self.advanced_format_selection_frame.setEnabled(False) self.advanced_format_selection_checkBox.toggled.connect( self.advancedFormatFrame) self.url_submit_pushButtontton.clicked.connect(self.submitClicked) self.media_comboBox.activated.connect( partial(self.mediaSelectionChanged, 'video_audio')) self.video_format_selection_comboBox.activated.connect( partial(self.mediaSelectionChanged, 'video')) self.audio_format_selection_comboBox.activated.connect( partial(self.mediaSelectionChanged, 'audio')) self.link_lineEdit.textChanged.disconnect( super().linkLineChanged) # Should be disconnected. self.link_lineEdit.textChanged.connect(self.linkLineChangedHere) self.setMinimumSize(650, 480) self.status_box_textEdit.hide() self.format_selection_frame.hide() self.advanced_format_selection_frame.hide() self.advanced_format_selection_checkBox.hide() if 'link' in video_dict.keys() and video_dict['link']: self.link_lineEdit.setText(video_dict['link']) self.url_submit_pushButtontton.setEnabled(True) else: # check clipboard clipboard = QApplication.clipboard() text = clipboard.text() if (("tp:/" in text[2:6]) or ("tps:/" in text[2:7])): self.link_lineEdit.setText(str(text)) self.url_submit_pushButtontton.setEnabled(True) def advancedFormatFrame(self, button): if self.advanced_format_selection_checkBox.isChecked(): self.advanced_format_selection_frame.setEnabled(True) self.format_selection_frame.setEnabled(False) self.mediaSelectionChanged( 'video', int(self.video_format_selection_comboBox.currentIndex())) else: self.advanced_format_selection_frame.setEnabled(False) self.format_selection_frame.setEnabled(True) self.mediaSelectionChanged('video_audio', int(self.media_comboBox.currentIndex())) def getReadableSize(self, size): try: return '{:1.2f} MB'.format(int(size) / 1048576) except: return str(size) def getReadableDuration(self, seconds): try: seconds = int(seconds) hours = seconds // 3600 seconds = seconds % 3600 minutes = seconds // 60 seconds = seconds % 60 return '{:02d}:{:02d}:{:02d}'.format(hours, minutes, seconds) except: return str(seconds) # Define native slots def urlChanged(self, value): if ' ' in value or value == '': self.url_submit_pushButtontton.setEnabled(False) self.url_submit_pushButtontton.setToolTip( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Please enter a valid video link')) else: self.url_submit_pushButtontton.setEnabled(True) self.url_submit_pushButtontton.setToolTip('') def submitClicked(self, button=None): # Clear media list self.media_comboBox.clear() self.format_selection_frame.hide() self.advanced_format_selection_checkBox.hide() self.advanced_format_selection_frame.hide() self.video_format_selection_comboBox.clear() self.audio_format_selection_comboBox.clear() self.change_name_lineEdit.clear() self.threadPool.clear() self.change_name_checkBox.setChecked(False) self.video_audio_list.clear() self.no_video_list.clear() self.no_audio_list.clear() self.url_submit_pushButtontton.setEnabled(False) self.status_box_textEdit.setText( QCoreApplication.translate("ytaddlink_src_ui_tr", 'Fetching Media Info...')) self.status_box_textEdit.show() self.ok_pushButton.setEnabled(False) self.download_later_pushButton.setEnabled(False) dictionary_to_send = deepcopy(self.plugin_add_link_dictionary) # More options more_options = self.collectMoreOptions() for k in more_options.keys(): dictionary_to_send[k] = more_options[k] dictionary_to_send['link'] = self.link_lineEdit.text() fetcher_thread = MediaListFetcherThread(self.fetchedResult, dictionary_to_send, self) self.parent.threadPool.append(fetcher_thread) self.parent.threadPool[len(self.parent.threadPool) - 1].start() def fileNameChanged(self, value): if value.strip() == '': self.ok_pushButton.setEnabled(False) def mediaSelectionChanged(self, combobox, index): try: if combobox == 'video_audio': if self.media_comboBox.currentText() == 'Best quality': self.change_name_lineEdit.setText(self.media_title) self.extension_label.setText('.' + self.no_audio_list[-1]['ext']) else: self.change_name_lineEdit.setText(self.media_title) self.extension_label.setText( '.' + self.video_audio_list[index]['ext']) self.change_name_checkBox.setChecked(True) elif combobox == 'video': if self.video_format_selection_comboBox.currentText( ) != 'No video': self.change_name_lineEdit.setText(self.media_title) self.extension_label.setText('.' + self.no_audio_list[index - 1]['ext']) self.change_name_checkBox.setChecked(True) else: if self.audio_format_selection_comboBox.currentText( ) != 'No audio': self.change_name_lineEdit.setText(self.media_title) self.extension_label.setText('.' + self.no_video_list[ int(self.audio_format_selection_comboBox. currentIndex()) - 1]['ext']) self.change_name_checkBox.setChecked(True) else: self.change_name_lineEdit.setChecked(False) elif combobox == 'audio': if self.audio_format_selection_comboBox.currentText( ) != 'No audio' and self.video_format_selection_comboBox.currentText( ) == 'No video': self.change_name_lineEdit.setText(self.media_title) self.extension_label.setText('.' + self.no_video_list[index - 1]['ext']) self.change_name_checkBox.setChecked(True) elif (self.audio_format_selection_comboBox.currentText() == 'No audio' and self.video_format_selection_comboBox.currentText() != 'No video') or ( self.audio_format_selection_comboBox.currentText() != 'No audio' and self.video_format_selection_comboBox.currentText() != 'No video'): self.change_name_lineEdit.setText(self.media_title) self.extension_label.setText('.' + self.no_audio_list[ int(self.video_format_selection_comboBox.currentIndex( )) - 1]['ext']) self.change_name_checkBox.setChecked(True) elif self.audio_format_selection_comboBox.currentText( ) == 'No audio' and self.video_format_selection_comboBox.currentText( ) == 'No video': self.change_name_checkBox.setChecked(False) except Exception as ex: logger.sendToLog(ex, "ERROR") def fetchedResult(self, media_dict): self.url_submit_pushButtontton.setEnabled(True) if 'error' in media_dict.keys(): self.status_box_textEdit.setText('<font color="#f11">' + str(media_dict['error']) + '</font>') self.status_box_textEdit.show() else: # Show the media list # add no audio and no video options to the comboboxes self.video_format_selection_comboBox.addItem('No video') self.audio_format_selection_comboBox.addItem('No audio') self.media_title = media_dict['title'] if 'formats' not in media_dict.keys( ) and 'entries' in media_dict.keys(): formats = media_dict['entries'] formats = formats[0] media_dict['formats'] = formats['formats'] elif 'formats' not in media_dict.keys( ) and 'format' in media_dict.keys(): media_dict['formats'] = [media_dict.copy()] try: i = 0 for f in media_dict['formats']: no_audio = False no_video = False text = '' if 'acodec' in f.keys(): # only video, no audio if f['acodec'] == 'none': no_audio = True # resolution if 'height' in f.keys(): text = text + ' ' + '{}p'.format(f['height']) if 'vcodec' in f.keys(): # if f['vcodec'] == 'none' and f['acodec'] != 'none': # continue # No video, show audio bit rate if f['vcodec'] == 'none': text = text + '{}kbps'.format(f['abr']) no_video = True if 'ext' in f.keys(): text = text + ' ' + '.{}'.format(f['ext']) if 'filesize' in f.keys() and f['filesize']: # Youtube api does not supply file size for some formats, so check it. text = text + ' ' + '{}'.format( self.getReadableSize(f['filesize'])) else: # Start spider to find file size input_dict = deepcopy(self.plugin_add_link_dictionary) input_dict['link'] = f['url'] more_options = self.collectMoreOptions() for key in more_options.keys(): input_dict[key] = more_options[key] size_fetcher = FileSizeFetcherThread(input_dict, i) self.threadPool[str(i)] = { 'thread': size_fetcher, 'item_id': i } self.parent.threadPool.append(size_fetcher) self.parent.threadPool[len(self.parent.threadPool) - 1].start() self.parent.threadPool[len(self.parent.threadPool) - 1].FOUND.connect( self.findFileSize) # Add current format to the related comboboxes if no_audio: self.no_audio_list.append(f) self.video_format_selection_comboBox.addItem(text) elif no_video: self.no_video_list.append(f) self.audio_format_selection_comboBox.addItem(text) else: self.video_audio_list.append(f) self.media_comboBox.addItem(text) i = i + 1 self.status_box_textEdit.hide() if 'duration' in media_dict.keys(): self.duration_label.setText( 'Duration ' + self.getReadableDuration(media_dict['duration'])) self.format_selection_frame.show() self.advanced_format_selection_checkBox.show() self.advanced_format_selection_frame.show() self.ok_pushButton.setEnabled(True) self.download_later_pushButton.setEnabled(True) # if we have no options for seperate audio and video, then hide advanced_format_selection... if len(self.no_audio_list) == 0 and len( self.no_video_list) == 0: self.advanced_format_selection_checkBox.hide() self.advanced_format_selection_frame.hide() # set index of comboboxes on best available quality. if len(self.no_audio_list) != 0 and len( self.no_video_list) != 0: self.media_comboBox.addItem('Best quality') self.media_comboBox.setCurrentIndex( len(self.video_audio_list)) elif len(self.video_audio_list) != 0: self.media_comboBox.setCurrentIndex( len(self.video_audio_list) - 1) if len(self.no_audio_list) != 0: self.video_format_selection_comboBox.setCurrentIndex( len(self.no_audio_list)) if len(self.no_video_list) != 0: self.audio_format_selection_comboBox.setCurrentIndex( len(self.no_video_list)) self.mediaSelectionChanged( 'video_audio', int(self.media_comboBox.currentIndex())) except Exception as ex: logger.sendToLog(ex, "ERROR") def findFileSize(self, result): try: item_id = self.threadPool[str(result['thread_key'])]['item_id'] if result['file_size'] and result['file_size'] != '0': text = self.media_comboBox.itemText(item_id) self.media_comboBox.setItemText( item_id, '{} - {}'.format(text, result['file_size'])) except Exception as ex: logger.sendToLog(ex, "ERROR") def linkLineChangedHere(self, lineEdit): if str(lineEdit) == '': self.url_submit_pushButtontton.setEnabled(False) else: self.url_submit_pushButtontton.setEnabled(True) # This method collects additional information like proxy ip, user, password etc. def collectMoreOptions(self): options = { 'ip': None, 'port': None, 'proxy_user': None, 'proxy_passwd': None, 'download_user': None, 'download_passwd': None } if self.proxy_checkBox.isChecked(): options['ip'] = self.ip_lineEdit.text() options['port'] = self.port_spinBox.value() options['proxy_user'] = self.proxy_user_lineEdit.text() options['proxy_passwd'] = self.proxy_pass_lineEdit.text() if self.download_checkBox.isChecked(): options['download_user'] = self.download_user_lineEdit.text() options['download_passwd'] = self.download_pass_lineEdit.text() # These info (keys) are required for spider to find file size, because spider() does not check if key exists. additional_info = [ 'header', 'load_cookies', 'user_agent', 'referer', 'out' ] for i in additional_info: if i not in self.plugin_add_link_dictionary.keys(): options[i] = None return options # user commited information by pressing ok_pushButton, so get information # from VideoFinderAddLink window and return them to the mainwindow with callback! def okButtonPressed(self, button, download_later): link_list = [] # seperate audio format and video format is selected. if self.advanced_format_selection_checkBox.isChecked(): if self.video_format_selection_comboBox.currentText( ) == 'No video' and self.audio_format_selection_comboBox.currentText( ) != 'No audio': # only audio link must be added to the link_list audio_link = self.no_video_list[ self.audio_format_selection_comboBox.currentIndex() - 1]['url'] link_list.append(audio_link) elif self.video_format_selection_comboBox.currentText( ) != 'No video' and self.audio_format_selection_comboBox.currentText( ) == 'No audio': # only video link must be added to the link_list video_link = self.no_audio_list[ self.video_format_selection_comboBox.currentIndex() - 1]['url'] link_list.append(video_link) elif self.video_format_selection_comboBox.currentText( ) != 'No video' and self.audio_format_selection_comboBox.currentText( ) != 'No audio': # video and audio links must be added to the link_list audio_link = self.no_video_list[ self.audio_format_selection_comboBox.currentIndex() - 1]['url'] video_link = self.no_audio_list[ self.video_format_selection_comboBox.currentIndex() - 1]['url'] link_list = [video_link, audio_link] elif self.video_format_selection_comboBox.currentText( ) == 'No video' and self.audio_format_selection_comboBox.currentText( ) == 'No audio': # no video and no video selected! REALY?!. user is DRUNK! close the window! :)) self.close() else: if self.media_comboBox.currentText() == 'Best quality': # the last item in no_video_list and no_audio_list are the best. audio_link = self.no_video_list[-1]['url'] video_link = self.no_audio_list[-1]['url'] link_list = [video_link, audio_link] else: audio_and_video_link = self.video_audio_list[ self.media_comboBox.currentIndex()]['url'] link_list.append(audio_and_video_link) # write user's new inputs in persepolis_setting for next time :) self.persepolis_setting.setValue('add_link_initialization/ip', self.ip_lineEdit.text()) self.persepolis_setting.setValue('add_link_initialization/port', self.port_spinBox.value()) self.persepolis_setting.setValue('add_link_initialization/proxy_user', self.proxy_user_lineEdit.text()) self.persepolis_setting.setValue( 'add_link_initialization/download_user', self.download_user_lineEdit.text()) # get proxy information if not (self.proxy_checkBox.isChecked()): ip = None port = None proxy_user = None proxy_passwd = None else: ip = self.ip_lineEdit.text() if not (ip): ip = None port = self.port_spinBox.value() if not (port): port = None proxy_user = self.proxy_user_lineEdit.text() if not (proxy_user): proxy_user = None proxy_passwd = self.proxy_pass_lineEdit.text() if not (proxy_passwd): proxy_passwd = None # get download username and password information if not (self.download_checkBox.isChecked()): download_user = None download_passwd = None else: download_user = self.download_user_lineEdit.text() if not (download_user): download_user = None download_passwd = self.download_pass_lineEdit.text() if not (download_passwd): download_passwd = None # check that if user limits download speed. if not (self.limit_checkBox.isChecked()): limit = 0 else: if self.limit_comboBox.currentText() == "KiB/s": limit = str(self.limit_spinBox.value()) + str("K") else: limit = str(self.limit_spinBox.value()) + str("M") # get start time for download if user set that. if not (self.start_checkBox.isChecked()): start_time = None else: start_time = self.start_time_qDataTimeEdit.text() # get end time for download if user set that. if not (self.end_checkBox.isChecked()): end_time = None else: end_time = self.end_time_qDateTimeEdit.text() # set name for file(s) if self.change_name_checkBox.isChecked(): name = str(self.change_name_lineEdit.text()) if name == '': name = 'video_finder_file' else: name = 'video_finder_file' # video finder always finds extension # but if it can't find file extension # use mp4 for extension. if str(self.extension_label.text()) == '': extension = '.mp4' else: extension = str(self.extension_label.text()) # did user select seperate audio and video? if len(link_list) == 2: video_name = name + extension audio_name = name + '.' + str(self.no_video_list[ self.audio_format_selection_comboBox.currentIndex() - 1]['ext']) name_list = [video_name, audio_name] else: name_list = [name + extension] # get number of connections connections = self.connections_spinBox.value() # get download_path download_path = self.download_folder_lineEdit.text() # referer if self.referer_lineEdit.text() != '': referer = self.referer_lineEdit.text() else: referer = None # header if self.header_lineEdit.text() != '': header = self.header_lineEdit.text() else: header = None # user_agent if self.user_agent_lineEdit.text() != '': user_agent = self.user_agent_lineEdit.text() else: user_agent = None # load_cookies if self.load_cookies_lineEdit.text() != '': load_cookies = self.load_cookies_lineEdit.text() else: load_cookies = None add_link_dictionary_list = [] if len(link_list) == 1: # save information in a dictionary(add_link_dictionary). add_link_dictionary = { 'referer': referer, 'header': header, 'user_agent': user_agent, 'load_cookies': load_cookies, 'out': name_list[0], 'start_time': start_time, 'end_time': end_time, 'link': link_list[0], 'ip': ip, 'port': port, 'proxy_user': proxy_user, 'proxy_passwd': proxy_passwd, 'download_user': download_user, 'download_passwd': download_passwd, 'connections': connections, 'limit_value': limit, 'download_path': download_path } add_link_dictionary_list.append(add_link_dictionary) else: video_add_link_dictionary = { 'referer': referer, 'header': header, 'user_agent': user_agent, 'load_cookies': load_cookies, 'out': name_list[0], 'start_time': start_time, 'end_time': end_time, 'link': link_list[0], 'ip': ip, 'port': port, 'proxy_user': proxy_user, 'proxy_passwd': proxy_passwd, 'download_user': download_user, 'download_passwd': download_passwd, 'connections': connections, 'limit_value': limit, 'download_path': download_path } audio_add_link_dictionary = { 'referer': referer, 'header': header, 'user_agent': user_agent, 'load_cookies': load_cookies, 'out': name_list[1], 'start_time': None, 'end_time': end_time, 'link': link_list[1], 'ip': ip, 'port': port, 'proxy_user': proxy_user, 'proxy_passwd': proxy_passwd, 'download_user': download_user, 'download_passwd': download_passwd, 'connections': connections, 'limit_value': limit, 'download_path': download_path } add_link_dictionary_list = [ video_add_link_dictionary, audio_add_link_dictionary ] # get category of download category = str(self.add_queue_comboBox.currentText()) del self.plugin_add_link_dictionary # return information to mainwindow self.callback(add_link_dictionary_list, download_later, category) # close window self.close()
class GcodeEditor(QWidget, _HalWidgetBase): percentDone = pyqtSignal(int) def __init__(self, parent=None): super(GcodeEditor, self).__init__(parent) self.load_dialog_code = 'LOAD' self.save_dialog_code = 'SAVE' STATUS.connect('general', self.returnFromDialog) self.isCaseSensitive = 0 self.setMinimumSize(QSize(300, 200)) self.setWindowTitle("PyQt5 editor test example") lay = QVBoxLayout() lay.setContentsMargins(0, 0, 0, 0) self.setLayout(lay) # make editor self.editor = GcodeDisplay(self) # class patch editor's function to ours # so we get the lines percent update self.editor.emit_percent = self.emit_percent self.editor.setReadOnly(True) self.editor.setModified(False) ################################ # add menubar actions ################################ # Create new action newAction = QAction(QIcon.fromTheme('document-new'), 'New', self) newAction.setShortcut('Ctrl+N') newAction.setStatusTip('New document') newAction.triggered.connect(self.newCall) # Create open action openAction = QAction(QIcon.fromTheme('document-open'), '&Open', self) openAction.setShortcut('Ctrl+O') openAction.setStatusTip('Open document') openAction.triggered.connect(self.openCall) # Create save action saveAction = QAction(QIcon.fromTheme('document-save'), '&save', self) saveAction.setShortcut('Ctrl+S') saveAction.setStatusTip('save document') saveAction.triggered.connect(self.saveCall) # Create exit action exitAction = QAction(QIcon.fromTheme('application-exit'), '&Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.exitCall) # Create gcode lexer action gCodeLexerAction = QAction(QIcon.fromTheme('lexer.png'), '&Gcode\n lexer', self) gCodeLexerAction.setCheckable(1) gCodeLexerAction.setShortcut('Ctrl+G') gCodeLexerAction.setStatusTip('Set Gcode highlighting') gCodeLexerAction.triggered.connect(self.gcodeLexerCall) # Create gcode lexer action pythonLexerAction = QAction(QIcon.fromTheme('lexer.png'), '&python\n lexer', self) pythonLexerAction.setShortcut('Ctrl+P') pythonLexerAction.setStatusTip('Set Python highlighting') pythonLexerAction.triggered.connect(self.pythonLexerCall) # Create toolbar and add action toolBar = QToolBar('File') toolBar.addAction(newAction) toolBar.addAction(openAction) toolBar.addAction(saveAction) toolBar.addAction(exitAction) toolBar.addSeparator() # add lexer actions toolBar.addAction(gCodeLexerAction) toolBar.addAction(pythonLexerAction) toolBar.addSeparator() toolBar.addWidget( QLabel( '<html><head/><body><p><span style=" font-size:20pt; font-weight:600;">Edit Mode</span></p></body></html>' )) # create a frame for buttons box = QHBoxLayout() box.addWidget(toolBar) self.topMenu = QFrame() self.topMenu.setLayout(box) # add widgets lay.addWidget(self.topMenu) lay.addWidget(self.editor) lay.addWidget(self.createGroup()) self.readOnlyMode() def createGroup(self): self.bottomMenu = QFrame() self.searchText = QLineEdit(self) self.replaceText = QLineEdit(self) toolBar = QToolBar() # Create new action undoAction = QAction(QIcon.fromTheme('edit-undo'), 'Undo', self) undoAction.setStatusTip('Undo') undoAction.triggered.connect(self.undoCall) toolBar.addAction(undoAction) # create redo action redoAction = QAction(QIcon.fromTheme('edit-redo'), 'Redo', self) redoAction.setStatusTip('Undo') redoAction.triggered.connect(self.redoCall) toolBar.addAction(redoAction) toolBar.addSeparator() # create replace action replaceAction = QAction(QIcon.fromTheme('edit-find-replace'), 'Replace', self) replaceAction.triggered.connect(self.replaceCall) toolBar.addAction(replaceAction) # create find action findAction = QAction(QIcon.fromTheme('edit-find'), 'Find', self) findAction.triggered.connect(self.findCall) toolBar.addAction(findAction) # create next action nextAction = QAction(QIcon.fromTheme('go-previous'), 'Find Previous', self) nextAction.triggered.connect(self.nextCall) toolBar.addAction(nextAction) toolBar.addSeparator() # create case action caseAction = QAction(QIcon.fromTheme('edit-case'), 'Aa', self) caseAction.setCheckable(1) caseAction.triggered.connect(self.caseCall) toolBar.addAction(caseAction) box = QHBoxLayout() box.addWidget(toolBar) box.addWidget(self.searchText) box.addWidget(self.replaceText) box.addStretch(1) self.bottomMenu.setLayout(box) return self.bottomMenu # callback functions built for easy class patching ########## # want to refrain from renaming these functions as it will break # any class patch user's use # we split them like this so a user can intercept the callback # but still call the original functionality def caseCall(self): self.case() def case(self): self.isCaseSensitive -= 1 self.isCaseSensitive *= -1 print(self.isCaseSensitive) def exitCall(self): self.exit() def exit(self): if self.editor.isModified(): result = self.killCheck() if result: self.readOnlyMode() def findCall(self): self.find() def find(self): self.editor.search(str(self.searchText.text()), re=False, case=self.isCaseSensitive, word=False, wrap=False, fwd=True) def gcodeLexerCall(self): self.gcodeLexer() def gcodeLexer(self): self.editor.set_gcode_lexer() def nextCall(self): next(self) def __next__(self): self.editor.search(str(self.searchText.text()), False) self.editor.search_Next() def newCall(self): self.new() def new(self): if self.editor.isModified(): result = self.killCheck() if result: self.editor.new_text() def openCall(self): self.open() def open(self): self.getFileName() def openReturn(self, f): ACTION.OPEN_PROGRAM(f) self.editor.setModified(False) def pythonLexerCall(self): self.pythonLexer() def pythonLexer(self): self.editor.set_python_lexer() def redoCall(self): self.redo() def redo(self): self.editor.redo() def replaceCall(self): self.replace() def replace(self): self.editor.replace_text(str(self.replaceText.text())) def saveCall(self): self.save() def save(self): self.getSaveFileName() def saveReturn(self, fname): ACTION.SAVE_PROGRAM(self.editor.text(), fname) self.editor.setModified(False) ACTION.OPEN_PROGRAM(fname) def undoCall(self): self.undo() def undo(self): self.editor.undo() # helper functions ############################################ def _hal_init(self): # name the top and bottom frames so it's easier to style self.bottomMenu.setObjectName('%sBottomButtonFrame' % self.objectName()) self.topMenu.setObjectName('%sTopButtonFrame' % self.objectName()) self.editor.setObjectName('{}_display'.format(self.objectName())) def editMode(self): self.topMenu.show() self.bottomMenu.show() self.editor.setReadOnly(False) def readOnlyMode(self): self.topMenu.hide() self.bottomMenu.hide() self.editor.setReadOnly(True) def getFileName(self): mess = { 'NAME': self.load_dialog_code, 'ID': '%s__' % self.objectName(), 'TITLE': 'Load Editor' } STATUS.emit('dialog-request', mess) def getSaveFileName(self): mess = { 'NAME': self.save_dialog_code, 'ID': '%s__' % self.objectName(), 'TITLE': 'Save Editor' } STATUS.emit('dialog-request', mess) # process the STATUS return message def returnFromDialog(self, w, message): if message.get('NAME') == self.load_dialog_code: path = message.get('RETURN') code = bool(message.get('ID') == '%s__' % self.objectName()) if path and code: self.openReturn(path) elif message.get('NAME') == self.save_dialog_code: path = message.get('RETURN') code = bool(message.get('ID') == '%s__' % self.objectName()) if path and code: self.saveReturn(path) def killCheck(self): choice = QMessageBox.question( self, 'Warning!!', "This file has changed since loading...Still want to proceed?", QMessageBox.Yes | QMessageBox.No) if choice == QMessageBox.Yes: return True else: return False def emit_percent(self, percent): self.percentDone.emit(percent) def select_lineup(self): self.editor.select_lineup(None) def select_linedown(self): self.editor.select_linedown(None) def select_line(self, line): self.editor.highlight_line(None, line) def jump_line(self, jump): self.editor.jump_line(jump) def get_line(self): return self.editor.getCursorPosition()[0] + 1 def set_margin_width(self, width): self.editor.set_margin_width(width) def set_font(self, font): self.editor.font = font for i in range(0, 4): self.editor.lexer.setFont(font, i) def set_background_color(self, color): self.editor.set_background_color(color) # designer recognized getter/setters # auto_show_mdi status # These adjust the self.editor instance def set_auto_show_mdi(self, data): self.editor.auto_show_mdi = data def get_auto_show_mdi(self): return self.editor.auto_show_mdi def reset_auto_show_mdi(self): self.editor.auto_show_mdi = True auto_show_mdi_status = pyqtProperty(bool, get_auto_show_mdi, set_auto_show_mdi, reset_auto_show_mdi) # designer recognized getter/setters # auto_show_manual status def set_auto_show_manual(self, data): self.editor.auto_show_manual = data def get_auto_show_manual(self): return self.editor.auto_show_manual def reset_auto_show_manual(self): self.editor.auto_show_manual = True auto_show_manual_status = pyqtProperty(bool, get_auto_show_manual, set_auto_show_manual, reset_auto_show_manual)
class SecondTest(QWidget): def __init__(self): self.title = "test window" self.X = 100 self.Y = 100 self.Width = 300 self.Height = 300 super(SecondTest, self).__init__() self.init_window() def init_window(self): self.title = "It Is A Test Window" self.setWindowTitle(self.title) self.setGeometry(self.X, self.Y, self.Width, self.Height) self.create_gui() self.show() def create_gui(self): # creating spacer item self.VSpacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.HSpacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.MainLayout = QHBoxLayout() self.setLayout(self.MainLayout) # Menu Button's self.MenuLayout = QVBoxLayout() self.MainLayout.addLayout(self.MenuLayout) self.FirstSlide = QPushButton("First Slide") self.SecondSlide = QPushButton("Second Slide") self.ThirdSlide = QPushButton("Third Slide") self.FirstSlide.clicked.connect(lambda l: self.change_slide_count(1)) self.SecondSlide.clicked.connect(lambda l: self.change_slide_count(2)) self.ThirdSlide.clicked.connect(lambda l: self.change_slide_count(3)) self.SlideNumber = QLabel("1..........") self.MenuLayout.addWidget(self.FirstSlide) self.MenuLayout.addWidget(self.SecondSlide) self.MenuLayout.addWidget(self.ThirdSlide) self.MenuLayout.addWidget(self.SlideNumber) self.MenuLayout.addItem(self.VSpacerItem) #self.MainSlideFrame = QFrame() #self.MainLayout.addWidget(self.MainSlideFrame) #slide 1st self.SlideFrame1 = QFrame() self.SlideLayout1 = QHBoxLayout() self.SlideFrame1.setLayout(self.SlideLayout1) button = QPushButton("111111111111111111") self.SlideLayout1.addWidget(button) # slide 2st self.SlideFrame2 = QFrame() self.SlideLayout2 = QHBoxLayout() self.SlideFrame2.setLayout(self.SlideLayout2) button = QPushButton("222222222222") self.SlideLayout2.addWidget(button) # slide 3st self.SlideFrame3 = QFrame() self.SlideLayout3 = QHBoxLayout() self.SlideFrame3.setLayout(self.SlideLayout3) button = QPushButton("333333") self.SlideLayout3.addWidget(button) #self.MainSlideFrame.setLayout(self.SlideLayout1) #self.LastSlide = self.SlideLayout1 self.MainLayout.addWidget(self.SlideFrame1) self.MainLayout.addWidget(self.SlideFrame2) self.MainLayout.addWidget(self.SlideFrame3) def change_slide_count1(self, slide): if slide == 1: print(self.MainLayout) self.MainLayout.removeWidget(self.LastSlide) self.LastSlide = self.SlideFrame1 self.MainLayout.addWidget(self.SlideFrame1) self.SlideNumber.setText("1.....") elif slide == 2: self.MainLayout.removeWidget(self.LastSlide) self.LastSlide = self.SlideFrame2 self.MainLayout.addWidget(self.SlideFrame2) self.SlideNumber.setText("2.....") elif slide == 3: self.MainLayout.removeWidget(self.LastSlide) self.LastSlide = self.SlideFrame3 self.MainLayout.addWidget(self.SlideFrame3) self.SlideNumber.setText("3.....") def change_slide_count2(self, slide): if slide == 1: self.MainSlideFrame.setLayout(self.SlideLayout1) self.SlideNumber.setText("1.....") if slide == 2: self.MainSlideFrame.setLayout(self.SlideLayout2) self.SlideNumber.setText("2.....") if slide == 3: self.MainSlideFrame.setLayout(self.SlideLayout3) self.SlideNumber.setText("3.....") def change_slide_count(self, slide): if slide == 1: self.SlideFrame1.show() self.SlideFrame2.hide() self.SlideFrame3.hide() if slide == 2: self.SlideFrame2.show() self.SlideFrame3.hide() self.SlideFrame1.hide() if slide == 3: self.SlideFrame3.show() self.SlideFrame2.hide() self.SlideFrame1.hide()
class main_class(QWidget): def __init__(self): super().__init__() self.thread_subs = QThread() self.obj = thread_subtitles() self.obj.update_subtitles.connect(self.render_subtitles) self.obj.moveToThread(self.thread_subs) self.thread_subs.started.connect(self.obj.main) self.thread_subs.start() self.thread_translations = QThread() self.obj2 = thread_translations() self.obj2.get_translations.connect(self.render_popup) self.obj2.moveToThread(self.thread_translations) self.thread_translations.started.connect(self.obj2.main) self.thread_translations.start() # start the forms self.subtitles_base() self.subtitles_base2() self.popup_base() def clearLayout(self, layout): if layout == 'subs': layout = self.subtitles_vbox self.subtitles.hide() elif layout == 'subs2': layout = self.subtitles_vbox2 self.subtitles2.hide() elif layout == 'popup': layout = self.popup_vbox self.popup.hide() if layout is not None: while layout.count(): item = layout.takeAt(0) widget = item.widget() if widget is not None: widget.deleteLater() else: self.clearLayout(item.layout()) def subtitles_base(self): self.subtitles = QFrame() self.subtitles.setAttribute(Qt.WA_TranslucentBackground) self.subtitles.setWindowFlags(Qt.X11BypassWindowManagerHint) self.subtitles.setStyleSheet(config.style_subs) self.subtitles_vbox = QVBoxLayout(self.subtitles) self.subtitles_vbox.setSpacing(config.subs_padding_between_lines) self.subtitles_vbox.setContentsMargins(0, 0, 0, 0) def subtitles_base2(self): self.subtitles2 = QFrame() self.subtitles2.setAttribute(Qt.WA_TranslucentBackground) self.subtitles2.setWindowFlags(Qt.X11BypassWindowManagerHint) self.subtitles2.setStyleSheet(config.style_subs) self.subtitles_vbox2 = QVBoxLayout(self.subtitles2) self.subtitles_vbox2.setSpacing(config.subs_padding_between_lines) self.subtitles_vbox2.setContentsMargins(0, 0, 0, 0) if config.pause_during_translation_B: self.subtitles2.enterEvent = lambda event: [ mpv_pause(), setattr(config, 'block_popup', False) ][0] self.subtitles2.leaveEvent = lambda event: [ mpv_resume(), setattr(config, 'block_popup', True) ][0] if not config.avoid_resuming else [ setattr(config, 'avoid_resuming', False), setattr(config, 'block_popup', True) ][0] def popup_base(self): self.popup = QFrame() self.popup.setAttribute(Qt.WA_TranslucentBackground) self.popup.setWindowFlags(Qt.X11BypassWindowManagerHint) self.popup.setStyleSheet(config.style_popup) self.popup_inner = QFrame() outer_box = QVBoxLayout(self.popup) outer_box.addWidget(self.popup_inner) self.popup_vbox = QVBoxLayout(self.popup_inner) self.popup_vbox.setSpacing(0) def render_subtitles(self, hide=False, redraw=False): if hide or not len(subs): try: self.subtitles.hide() self.subtitles2.hide() finally: return if redraw: self.subtitles.setStyleSheet(config.style_subs) self.subtitles2.setStyleSheet(config.style_subs) else: self.clearLayout('subs') self.clearLayout('subs2') if hasattr(self, 'popup'): self.popup.hide() # if subtitle consists of one overly long line - split into two if config.split_long_lines_B and len( subs.split('\n')) == 1 and len(subs.split( ' ')) > config.split_long_lines_words_min - 1: subs2 = split_long_lines(subs) else: subs2 = subs subs2 = re.sub(' +', ' ', subs2).strip() ############################## for line in subs2.split('\n'): line2 = ' %s ' % line.strip() ll = drawing_layer(line2, subs2) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) hbox.setSpacing(0) hbox.addStretch() hbox.addWidget(ll) hbox.addStretch() self.subtitles_vbox.addLayout(hbox) #################################### hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) hbox.setSpacing(0) hbox.addStretch() if config.R2L_from_B: line2 = line2[::-1] line2 += '\00' word = '' for smbl in line2: if smbl.isalpha(): word += smbl else: if len(word): if config.R2L_from_B: word = word[::-1] ll = events_class(word, subs2) ll.mouseHover.connect(self.render_popup) ll.redraw.connect(self.render_subtitles) hbox.addWidget(ll) word = '' if smbl != '\00': ll = events_class(smbl, subs2, skip=True) hbox.addWidget(ll) hbox.addStretch() self.subtitles_vbox2.addLayout(hbox) self.subtitles.adjustSize() self.subtitles2.adjustSize() w = self.subtitles.geometry().width() h = self.subtitles.height = self.subtitles.geometry().height() x = (config.screen_width / 2) - (w / 2) if config.subs_top_placement_B: y = config.subs_screen_edge_padding else: y = config.screen_height - config.subs_screen_edge_padding - h self.subtitles.setGeometry(int(x), int(y), 0, 0) self.subtitles.show() self.subtitles2.setGeometry(int(x), int(y), 0, 0) self.subtitles2.show() def render_popup(self, text, x_cursor_pos, is_line): if text == '': if hasattr(self, 'popup'): self.popup.hide() return self.clearLayout('popup') if is_line: QApplication.setOverrideCursor(Qt.WaitCursor) line = globals()[config.translation_function_name_full_sentence]( text) if config.translation_function_name_full_sentence == 'google': try: line = line[0][0][0].strip() except: line = 'Google translation failed.' if config.split_long_lines_B and len( line.split('\n')) == 1 and len(line.split( ' ')) > config.split_long_lines_words_min - 1: line = split_long_lines(line) ll = QLabel(line) ll.setObjectName("first_line") self.popup_vbox.addWidget(ll) else: word = text for translation_function_name_i, translation_function_name in enumerate( config.translation_function_names): pairs, word_descr = globals()[translation_function_name](word) if not len(pairs): pairs = [['', '[Not found]']] #return # ~pairs = [ [ str(i) + ' ' + pair[0], pair[1] ] for i, pair in enumerate(pairs) ] if word in config.scroll: if len(pairs[config.scroll[word]:] ) > config.number_of_translations: pairs = pairs[config.scroll[word]:] else: pairs = pairs[-config.number_of_translations:] if len(config.translation_function_names) == 1: config.scroll[word] -= 1 for i1, pair in enumerate(pairs): if i1 == config.number_of_translations: break if config.split_long_lines_in_popup_B: pair[0] = split_long_lines( pair[0], max_symbols_per_line=config. split_long_lines_in_popup_symbols_min) pair[1] = split_long_lines( pair[1], max_symbols_per_line=config. split_long_lines_in_popup_symbols_min) if pair[0] == '-': pair[0] = '' if pair[1] == '-': pair[1] = '' # ~if config.R2L_from_B: # ~pair[0] = pair[0][::-1] # ~if config.R2L_to_B: # ~pair[1] = pair[1][::-1] if pair[0] != '': # to emphasize the exact form of the word # to ignore case on input and match it on output chnks = re.split(word, pair[0], flags=re.I) exct_words = re.findall(word, pair[0], flags=re.I) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) for i2, chnk in enumerate(chnks): if len(chnk): ll = QLabel(chnk) ll.setObjectName("first_line") hbox.addWidget(ll) if i2 + 1 < len(chnks): ll = QLabel(exct_words[i2]) ll.setObjectName("first_line_emphasize_word") hbox.addWidget(ll) # filling the rest of the line with empty bg ll = QLabel() ll.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) hbox.addWidget(ll) self.popup_vbox.addLayout(hbox) if pair[1] != '': ll = QLabel(pair[1]) ll.setObjectName("second_line") self.popup_vbox.addWidget(ll) # padding ll = QLabel() ll.setStyleSheet("font-size: 6px;") self.popup_vbox.addWidget(ll) if len(word_descr[0]): ll = QLabel(word_descr[0]) ll.setProperty("morphology", word_descr[1]) ll.setAlignment(Qt.AlignRight) self.popup_vbox.addWidget(ll) # delimiter between dictionaries if translation_function_name_i + 1 < len( config.translation_function_names): ll = QLabel() ll.setObjectName("delimiter") self.popup_vbox.addWidget(ll) self.popup_inner.adjustSize() self.popup.adjustSize() w = self.popup.geometry().width() h = self.popup.geometry().height() if w > config.screen_width: w = config.screen_width - 20 if not is_line: if w < config.screen_width / 3: w = config.screen_width / 3 if x_cursor_pos == -1: x = (config.screen_width / 2) - (w / 2) else: x = x_cursor_pos - w / 5 if x + w > config.screen_width: x = config.screen_width - w if config.subs_top_placement_B: y = self.subtitles.height + config.subs_screen_edge_padding else: y = config.screen_height - config.subs_screen_edge_padding - self.subtitles.height - h self.popup.setGeometry(int(x), int(y), int(w), 0) self.popup.show() QApplication.restoreOverrideCursor()
def dialog_box(title, icon, errorText, warningText): dlg = QDialog() scroll = QScrollArea(dlg) widget = QWidget() vbox = QVBoxLayout() labelN = QLabel(notice, objectName='labelN') lineE = QFrame(objectName='lineE') lineE.setFrameShape(QFrame.HLine) labelE1 = QLabel(objectName='labelE1') labelE2 = QLabel() lineW = QFrame(objectName='lineW') lineW.setFrameShape(QFrame.HLine) labelW1 = QLabel(objectName='labelW1') labelW2 = QLabel() vbox.addWidget(labelN) vbox.addWidget(lineE) vbox.addWidget(labelE1) vbox.addWidget(labelE2) vbox.addWidget(lineW) vbox.addWidget(labelW1) vbox.addWidget(labelW2) widget.setLayout(vbox) btn = QPushButton('OK', dlg) dlg.setWindowTitle(title) dlg.setWindowIcon(QIcon(dlg.style().standardIcon(icon))) dlg.setWindowFlags(Qt.WindowStaysOnTopHint) dlg.setModal(False) dlg.setFixedWidth(600) dlg.setFixedHeight(310) scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) scroll.setWidgetResizable(True) scroll.setWidget(widget) scroll.setGeometry(5, 5, 590, 250) btn.move(270, 260) btn.clicked.connect(lambda w: dlg_ok_clicked(dlg)) if errorText: labelE1.setText(errors) labelE2.setText(errorText) else: lineE.hide() labelE1.hide() labelE2.hide() if warningText: labelW1.setText(warnings) labelW2.setText(warningText) else: lineW.hide() labelW1.hide() labelW2.hide() dlg.setStyleSheet(' \ * {{ color: {0}; background: {1}}} \ QScrollArea {{color:{0}; background:{1}; border:1px solid {0}; border-radius:4px; padding:4px}} \ QPushButton {{border:2px solid {0}; border-radius:4px; font:12pt; width:60px; height:40px}} \ QPushButton:pressed {{border:1px solid {0}}} \ QScrollBar:vertical {{background:{2}; border:0px; border-radius:4px; margin: 0px; width:20px}} \ QScrollBar::handle:vertical {{background:{0}; border:2px solid {0}; border-radius:4px; margin:2px; min-height:40px}} \ QScrollBar::add-line:vertical {{height:0px}} \ QScrollBar::sub-line:vertical {{height:0px}} \ QVboxLayout {{margin:100}} \ #labelN {{font-style:italic}} \ #lineE, #lineW {{border:1px solid {0}}} \ #labelE1, #labelW1 {{font-weight:bold}}'.format( fgColor, bgColor, bgAltColor)) dlg.exec()
class LineFrame(QFrame): def __init__(self, father, top, name, space=1, text=''): super().__init__(father) self.setProperty('cate', 'line_frame') self.father, self.top, self.index = father, top, name self.width_ = self.top.size_[0] self.setObjectName(str(name)) self.space = 1 self.origin_text = text self.origin_space = space - 1 self.color_index = name % len(self.father.color_list) self.hide_list = [] self.edit_lock = False self.init() def init(self): self.left_frame = QFrame(self) left_layout = QVBoxLayout(self.left_frame) self.time_label = QLabel( '<b>%s:%s0</b>' % (self.index // 2, (self.index % 2) * 3), self.left_frame) self.color_button = QPushButton(' ', self.left_frame) self.color_button.setFixedSize(30, 20) self.color_button.clicked.connect(self.change_color) self.color_button.setProperty('cate', 'palette') if (self.index % 2) == 0: self.time_label.setProperty('cate', 'hour') else: self.time_label.setProperty('cate', 'minute') self.time_label.setFixedSize(45, 20) left_layout.addWidget(self.time_label, alignment=Qt.AlignTop) left_layout.addWidget(self.color_button, alignment=Qt.AlignCenter) self.left_frame.setLayout(left_layout) self.left_frame.move(0, 0) self.edit = QTextEdit(self) self.edit.selectionChanged.connect(self.align_) self.edit.move(60, 0) self.right_frame = QFrame(self) btn_layout = QVBoxLayout(self.right_frame) self.add_button = QPushButton('', self.right_frame) self.del_button = QPushButton('', self.right_frame) self.add_button.setProperty('cate', 'add') self.del_button.setProperty('cate', 'del') self.add_button.clicked.connect(lambda: self.add_del('a')) self.del_button.clicked.connect(lambda: self.add_del('d')) self.add_button.setFixedSize(30, 30) self.del_button.setFixedSize(30, 30) btn_layout.addWidget(self.add_button, alignment=Qt.AlignCenter) btn_layout.addWidget(self.del_button, alignment=Qt.AlignCenter) self.right_frame.setLayout(btn_layout) self.right_frame.move(self.top.size_[0] - 60, 0) self.refresh() self.change_color() # 初始化edit内容和行占位 def init_height(self): self.edit.setText(self.origin_text) self.edit.setTextColor(QColor(0, 0, 0)) while self.origin_space > 0: self.origin_space -= 1 self.add_del('a') self.edit.setAlignment(Qt.AlignHCenter) # 随时改变居中 def align_(self): if not self.edit_lock: self.edit_lock = True self.edit.setAlignment(Qt.AlignHCenter) self.edit_lock = False # 打开/关闭编辑 def alter(self, do, old_space=None): if do: self.right_frame.show() self.edit.verticalScrollBar().show() self.color_button.show() self.add_button.show() self.edit.setEnabled(True) width = 0.72 if self.space > 1: self.del_button.show() else: self.del_button.hide() else: self.right_frame.hide() self.edit.verticalScrollBar().hide() self.color_button.hide() self.edit.setEnabled(False) width = 0.83 if old_space: self.size_animal(self.edit, old_space, self.space, self.top.size_[0] * width, (60, 0), (60, 0)) else: self.edit.setGeometry(60, 0, self.top.size_[0] * width, 50 * self.space) self.edit.setAlignment(Qt.AlignHCenter) # 增减行占位 def add_del(self, what): old_space = self.space if what == 'a' and self.space < 22: c = self.father.update_line(self.index + self.space, True) self.space += c elif what == 'd' and self.space > 1: self.space -= 1 self.father.update_line(self.index + self.space, False) self.refresh(old_space=old_space, active=True) # 隐藏行 def hide_(self): old_space = self.space self.space = 0 self.refresh(old_space=old_space) return old_space # 显示行 def show_(self): self.space = 1 self.refresh(old_space=0, active=True) # 更新行大小 def refresh(self, old_space=None, active=False): if not old_space and old_space != 0: self.setGeometry(0, self.index * 50, self.width_, self.space * 50) self.left_frame.setGeometry(0, 0, 60, self.space * 50) self.right_frame.setGeometry(self.width_ - 60, 0, 60, 50 * self.space) else: if not active: new_y = (self.index + abs(old_space - self.space)) * 50 elif old_space == 0: self.move(0, self.index * 50 + 50) new_y = self.index * 50 else: new_y = self.index * 50 self.size_animal(self, old_space, self.space, self.width_, [self.pos().x(), self.pos().y()], [0, new_y]) self.size_animal(self.left_frame, old_space, self.space, 60, (0, 0), (0, 0)) self.size_animal(self.right_frame, old_space, self.space, 60, (self.width_ - 60, 0), (self.width_ - 60, 0)) self.alter(True, old_space=old_space) # 调色板 def change_color(self): self.color_index = (self.color_index + 1) % len(self.father.color_list) color = self.father.color_list[self.color_index] self.edit.setStyleSheet('QTextEdit{background-color: %s;}' % color) # 到点提醒 def clock(self, time): if self.edit.toPlainText(): self.top.tray.show_a_message(time, self.edit.toPlainText()) # 动画效果 def size_animal(self, obj, old_space, new_space, width, old_position, new_position): # 动画效果 animal = QPropertyAnimation(obj, b'geometry', self) animal.setDuration(200) animal.setStartValue(QRect(*old_position, width, 50 * old_space)) animal.setEndValue(QRect(*new_position, width, 50 * new_space)) animal.start()
class catEditor(QDialog): """ """ def __init__(self,parent=None,): super().__init__(parent) self.defaultData = None buttonBox = QDialogButtonBox(QDialogButtonBox.Ok| QDialogButtonBox.Cancel) self.msgLine = QLabel() clauseLbl = QLabel('Eliga el proceso de categorias') self.sheet = WSheet(5,3,catDelegate) self.sheet.setHorizontalHeaderLabels(('Resultado','Op','Valores ')) defaultLbl = QLabel('Valor por defecto ') self.defaultValue = QLineEdit() resultLbl = QLabel('Valor a devolver') self.resultLE = QLineEdit() self.conditionCB = QComboBox() conditionLbl = QLabel('Clausula logica') self.conditionCB.addItems(('in','between','not in','not between','=','!=','>','<=','>','>=')) #FIXME normalizar valoresLb = QLabel('Valores') self.valuesLE = QLineEdit() self.groupFrame = QFrame() self.detailFrame = QFrame() groupLayout = QVBoxLayout() detailLayout = QVBoxLayout() meatlayout = QVBoxLayout() groupLayout.addWidget(clauseLbl) groupLayout.addWidget(self.sheet) groupLayout.addWidget(defaultLbl) groupLayout.addWidget(self.defaultValue) self.groupFrame.setLayout(groupLayout) detailLayout.addWidget(resultLbl) detailLayout.addWidget(self.resultLE) detailLayout.addWidget(conditionLbl) detailLayout.addWidget(self.conditionCB) detailLayout.addWidget(valoresLb) detailLayout.addWidget(self.valuesLE) self.detailFrame.setLayout(detailLayout) meatlayout.addWidget(self.groupFrame) meatlayout.addWidget(self.detailFrame) meatlayout.addWidget(self.msgLine) meatlayout.addWidget(buttonBox) self.setLayout(meatlayout) self.detailFrame.hide() self.groupFrame.show() # en esta posicion para que las señales se activen tras la inicializacion buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) self.sheet.resized.connect(self.resizeSheet) def setData(self,dato): self.defaultData = dato self.__setData(dato) def __setData(self,dato): if not dato: return if isinstance(dato[0],(list,tuple)): self.groupFrame.show() self.detailFrame.hide() if len(dato) > self.sheet.rowCount(): for k in range(self.sheet.rowCount(),len(dato)): self.sheet.addRow(emit=False) i = 0 for linea in dato: if linea[0] == "default": self.defaultValue.setText(linea[2]) continue for j,campo in enumerate(linea): if j >= self.sheet.columnCount(): break self.sheet.setData(i,j,campo) i += 1 for i in range(len(dato),self.sheet.rowCount()): self.sheet.initializeRow(i) elif dato[0] == 'default': self.groupFrame.hide() self.detailFrame.show() self.resultLE.setText(dato[0]) self.conditionCB.setCurrentText(dato[1]) self.valuesLE.setText(dato[2]) self.resultLE.setEnabled(False) self.conditionCB.hide() else: self.groupFrame.hide() self.detailFrame.show() self.resultLE.setText(dato[0]) self.conditionCB.setCurrentText(dato[1]) self.valuesLE.setText(dato[2]) self.resultLE.setEnabled(True) self.conditionCB.show() def getData(self): if not self.defaultData or isinstance(self.defaultData[0],(list,tuple)): dato = [] for i in range(self.sheet.rowCount()): linea = [] for j in range(self.sheet.columnCount()): linea.append(self.sheet.item(i,j).text()) dato.append(linea) if self.defaultValue.text() != "": dato.append(["default",None,self.defaultValue.text()]) return dato elif self.defaultData[0] == 'default': dato = [ None for k in range(3) ] dato[0] = 'default' dato[2] = self.valuesLE.text() return dato else: dato = [ None for k in range(3) ] dato[0] = self.resultLE.text() dato[1] = self.conditionCB.currentText() dato[2] = self.valuesLE.text() return dato def reject(self): self.__setData(self.defaultData) super().reject() def resizeSheet(self): #makeTableSize(self.sheet) totalwidth = self.sheet.size().width() self.sheet.setColumnWidth(0,totalwidth * 2 // 10) self.sheet.setColumnWidth(1,totalwidth * 1 //10) self.sheet.setColumnWidth(2,totalwidth * 7 //10)
class DownloaderDialog(JDialog): def __init__(self): super().__init__() self.setWindowIcon(QIcon('GUI\jinndl.ico')) self.setInitialSize(800, 800) self.initUi() self.setActions() def initUi(self): self.setWindowTitle("Download Jinn") self.windowLayout = QVBoxLayout(self) # Advanced options # Stored in a QFrame, this is hidden or shown by self.btnAdvancedOptions self.topBar = QHBoxLayout() self.btnAdvancedOptions = QPushButton("Show advanced options") self.comboBranch = LabelledComboBox("Choose branch:") self.comboBranch.cb.addItems(["HJinn", "LJinn", "master"]) self.advancedOptionsLayout = QHBoxLayout() self.advancedOptionsLayout.addWidget(self.comboBranch) self.advancedOptionsFrame = QFrame() self.advancedOptionsFrame.setHidden(True) self.advancedOptionsFrame.setLayout(self.advancedOptionsLayout) self.topBar.addWidget(self.btnAdvancedOptions) self.topBar.addWidget(self.advancedOptionsFrame) self.updateLog = JTextEdit( "Press 'Download' below to download the latest Jinn code to the USB memory stick" ) self.statusLayout = QVBoxLayout() self.statusLayout.addWidget(self.updateLog) self.btnDownload = JPushButton("Download") self.btnCancel = JCancelButton("Cancel") self.buttonBtm = QHBoxLayout() self.buttonBtm.addWidget(self.btnDownload) self.buttonBtm.addWidget(self.btnCancel) self.windowLayout.addLayout(self.topBar) self.windowLayout.addLayout(self.statusLayout) self.windowLayout.addLayout(self.buttonBtm) def setActions(self): self.btnAdvancedOptions.clicked.connect(self.showAdvancedOptions) self.btnDownload.clicked.connect(self.doDownload) self.btnCancel.clicked.connect(self.reject) def showAdvancedOptions(self): if self.advancedOptionsFrame.isHidden(): self.advancedOptionsFrame.show() self.btnAdvancedOptions.setText("Hide advanced options") else: self.advancedOptionsFrame.hide() self.btnAdvancedOptions.setText("Show advanced options") def getBranch(self): return self.comboBranch.cb.currentText() def doDownload(self): branch = self.getBranch() updateVariables = UpdateVariables(branch) try: cwd = os.getcwd() dirname = os.path.basename(cwd) if dirname.upper() == updateVariables.codeDir.upper(): raise Exception( "This script must not be run with the current directory being \"{}\"" ", because it needs to replace that directory".format(cwd)) # compute the root directory (`Jinn`) via where this script is being run from stdOut = setRootDir() updateJTextEdit(self.updateLog, stdOut) # download the zip file from github to the `Jinn` directory downloadZipFile(self.updateLog, updateVariables) # extract from the zip file to create `Jinn-master` directory in `Jinn` directory extractFromZipFile(self.updateLog, updateVariables) updateJTextEdit( self.updateLog, "Finished downloading and extracting latest Jinn code. Please insert the USB into your " "work computer and run the installer.") except Exception as ex: raise ex InfoMsgBox( "Finished", "Download has finished. You can now close the downloader and remove the USB stick. To continue " "upgrading Jinn plug this USB stick into your work PC and run the 'Jinn updater' shortcut", "Download finished").exec()
class MainWindow(CenterWindow): """ Displays list with tasks assigned to current user in JIRA """ def __init__(self, controller): super().__init__() self.setStyleSheet(QSS) self.controller = controller self.resize(1000, 600) self.setWindowTitle('JIRA Quick Reporter') self.setWindowIcon(QIcon(LOGO_PATH)) self.center() self.current_item = None self.vbox = QVBoxLayout() self.save_btn_box = QHBoxLayout() self.filter_name_label = QLabel() self.filter_name_label.setObjectName('filter_name_label') self.filter_name_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.filter_name_label.setAlignment(Qt.AlignLeft) self.filter_edited_label = QLabel('-> edited') self.filter_edited_label.setObjectName('filter_edited_label') self.filter_edited_label.hide() self.filter_edited_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.save_filter_btn = QPushButton('Save as') self.save_filter_btn.setObjectName('save_filter_btn') self.save_filter_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.save_filter_btn.clicked.connect(self.controller.save_filter) self.overwrite_filter_button = QPushButton('Save') self.overwrite_filter_button.setToolTip('You need to edit filter query first') self.overwrite_filter_button.setObjectName('save_filter_btn') self.overwrite_filter_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.overwrite_filter_button.clicked.connect(lambda: self.controller.save_filter(True)) self.delete_filter_btn = QPushButton() self.delete_filter_btn.setObjectName('delete_filter_btn') self.delete_filter_btn.clicked.connect(self.delete_filter) self.delete_filter_btn.setIcon(QIcon(DELETE_FILTER_ICON)) self.delete_filter_btn.setIconSize( QSize( self.delete_filter_btn.sizeHint().height(), self.delete_filter_btn.sizeHint().height() ) ) self.delete_filter_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.delete_filter_btn.setToolTip('Delete filter') self.save_btn_box.addWidget(self.filter_name_label, Qt.AlignLeft) self.save_btn_box.addWidget(self.filter_edited_label, Qt.AlignLeft) self.save_btn_box.addWidget(self.save_filter_btn, Qt.AlignLeft) self.save_btn_box.addWidget(self.overwrite_filter_button, Qt.AlignLeft) self.save_btn_box.addStretch() self.save_btn_box.addWidget(self.delete_filter_btn, Qt.AlignRight) self.create_filter_box = QHBoxLayout() self.query_field = QLineEdit() self.query_field.setObjectName('query_field') self.query_field.setPlaceholderText('You need to write a query here') self.action_help = QAction() self.action_help.setIcon(self.style().standardIcon(QStyle.SP_MessageBoxQuestion)) self.help_filter_url = QUrl(FILTER_FIELD_HELP_URL) self.action_help.triggered.connect(self.filter_field_help) self.query_field.addAction(self.action_help, QLineEdit.TrailingPosition) self.query_field.installEventFilter(self) self.search_issues_button = QPushButton('Search') self.search_issues_button.setObjectName('search_issues_button') self.search_issues_button.clicked.connect(self.controller.search_issues_by_query) self.create_filter_box.addWidget(self.query_field) self.create_filter_box.addWidget(self.search_issues_button) self.list_box = QVBoxLayout() self.issue_list_widget = QListWidget() self.issue_list_widget.setObjectName('issue_list') self.label_info = QLabel('You have no issues.') self.label_info.setAlignment(Qt.AlignCenter) self.list_box.addWidget(self.issue_list_widget) self.list_box.addWidget(self.label_info) self.label_info.hide() self.vbox.addLayout(self.save_btn_box) self.vbox.addLayout(self.create_filter_box) self.vbox.addLayout(self.list_box) self.filters_frame = QFrame() self.filters_frame.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.filters_frame.setFrameShape(QFrame.StyledPanel) self.filters_frame.setObjectName('filters_frame') self.filters_box = QVBoxLayout(self.filters_frame) self.filters_box_label = QLabel('Issues and filters') self.filters_box_label.setObjectName('filters_box_label') self.filters_box.addWidget(self.filters_box_label) self.filters_list = QListWidget() self.filters_list.installEventFilter(self) self.filters_list.itemClicked.connect(self.on_filter_selected) self.filters_list.setObjectName('filters_list') self.filters_list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.filters_box.addWidget(self.filters_list) self.add_filter_button = QPushButton('+') self.add_filter_button.clicked.connect(self.add_filter_btn_click) self.add_filter_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.filters_box.addWidget(self.add_filter_button, alignment=Qt.AlignRight) self.btn_box = QHBoxLayout() self.refresh_btn = QPushButton('Refresh') self.refresh_btn.clicked.connect(self.controller.refresh_issue_list) self.btn_box.addWidget(self.refresh_btn, alignment=Qt.AlignRight) self.vbox.addLayout(self.btn_box) self.toggle_frame_filters_btn = QPushButton('<') self.toggle_frame_filters_btn.clicked.connect(self.toggle_frame_filters) self.toggle_frame_filters_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.toggle_frame_filters_btn.setObjectName('toggle_filters_btn') self.main_box = QHBoxLayout() self.main_box.addWidget(self.filters_frame) self.main_box.addWidget(self.toggle_frame_filters_btn, alignment=Qt.AlignTop) self.main_box.addLayout(self.vbox) self.setLayout(self.main_box) self.tray_icon = QSystemTrayIcon(self) self.tray_icon.setIcon(QIcon(LOGO_PATH)) self.tray_menu = QMenu() self.action_open = QAction('Open JQR', self) self.action_quit = QAction('Quit JQR', self) self.tray_menu.addAction(self.action_open) self.action_open.triggered.connect(self.show_jqr_from_tray) self.tray_menu.addAction(self.action_quit) self.action_quit.triggered.connect(self.controller.quit_app) self.tray_icon.setContextMenu(self.tray_menu) self.tray_icon.show() self.timer_log_work = QTimer() self.timer_log_work.timeout.connect(self.notification_to_log_work) self.timer_log_work.start(LOG_TIME) self.timer_refresh = QTimer() self.timer_refresh.timeout.connect(self.controller.auto_refresh_issue_list) def show_jqr_from_tray(self): self.hide() self.setWindowFlags(self.windowFlags() & ~Qt.WindowStaysOnTopHint) self.activateWindow() self.show() def keyPressEvent(self, event): if event.key() == Qt.Key_Return: self.controller.search_issues_by_query() def notification_to_log_work(self): QSound.play(RING_SOUND_PATH) self.tray_icon.showMessage( '1 hour had passed', 'Don\'t forget to log your work!', msecs=2000 ) self.timer_log_work.start(LOG_TIME) def update_issues(self, update_list): for issue in update_list: item = self.issue_list_widget.findItems( issue['key'], Qt.MatchExactly )[0] item.setText(issue['key']) issue_widget = self.issue_list_widget.itemWidget(item) issue_widget.set_issue_key(issue['key'], issue['link']) issue_widget.set_issue_title(issue['title']) issue_widget.set_time( issue['estimated'], issue['logged'], issue['remaining'] ) issue_widget.set_workflow.clear() issue_widget.set_workflow.addItems(self.controller.get_possible_workflows(issue)) issue_widget.set_workflow.setCurrentIndex(0) issue_widget.set_workflow.activated[str].disconnect() issue_widget.set_workflow.activated[str].connect( partial( self.controller.change_workflow, issue['workflow'], issue['issue_obj'], ) ) def delete_issues(self, delete_list): for issue in delete_list: item = self.issue_list_widget.findItems( issue['key'], Qt.MatchExactly )[0] self.issue_list_widget.takeItem( self.issue_list_widget.row(item) ) def insert_issues(self, new_issues_list): for issue in new_issues_list: issue_widget = QCustomWidget() issue_widget.set_issue_key(issue['key'], issue['link']) issue_widget.set_issue_title(issue['title']) issue_widget.set_time( issue['estimated'], issue['logged'], issue['remaining'] ) issue_widget.quick_log_btn.clicked.connect( partial( self.controller.log_work_from_list, issue['key'] ) ) issue_widget.log_work_btn.clicked.connect( partial( self.controller.open_time_log, issue['key'] ) ) issue_widget.open_pomodoro_btn.clicked.connect( partial( self.controller.open_pomodoro_window, issue['key'], issue['title'] ) ) # add workflow statuses to dropdown possible_workflows = self.controller.get_possible_workflows(issue) issue_widget.set_workflow.addItems(possible_workflows) issue_widget.set_workflow.setCurrentIndex(0) issue_widget.set_workflow.activated[str].connect( partial( self.controller.change_workflow, issue['workflow'], issue['issue_obj'], ) ) # add issue item to list issue_list_widget_item = QListWidgetItem() issue_list_widget_item.setText(issue['key']) issue_list_widget_item.setSizeHint(issue_widget.sizeHint()) self.issue_list_widget.insertItem(issue['index'], issue_list_widget_item) self.issue_list_widget.setItemWidget( issue_list_widget_item, issue_widget ) self.set_size_hint() def set_size_hint(self): self.issue_list_widget.setMinimumWidth( self.issue_list_widget.sizeHintForColumn(0) + 50 ) self.issue_list_widget.setMinimumHeight( self.issue_list_widget.sizeHintForRow(0) * 2 ) def show_filters(self, filters_dict): for index, key in enumerate(filters_dict): if key == SEARCH_ITEM_NAME: self.filters_list.insertItem(0, key) else: self.filters_list.addItem(key) self.filters_list.item(index).setToolTip(key) self.filters_list.item(0).setText(self.filters_list.item(0).text().capitalize()) # add separator after first item separator = QFrame() separator.setFrameShape(QFrame.HLine) separator.setObjectName('separator') item_separator = QListWidgetItem() item_separator.setFlags(Qt.NoItemFlags) self.filters_list.insertItem(1, item_separator) self.filters_list.setItemWidget(item_separator, separator) self.filters_list.setCurrentItem( self.filters_list.findItems( MY_ISSUES_ITEM_NAME, Qt.MatchExactly )[0]) self.filters_list.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents) self.on_filter_selected(self.filters_list.currentItem()) def filter_field_help(self): QDesktopServices.openUrl(self.help_filter_url) def on_filter_selected(self, item): if not item.text(): return self.current_item = item if len(self.current_item.text()) > 50: set_text = '{}...'.format(self.current_item.text()[:50]) else: set_text = self.current_item.text() self.issue_list_widget.scrollToTop() self.controller.search_issues_by_filter_name(item.text()) self.filter_name_label.setText(set_text) self.filter_edited_label.hide() if self.filters_list.currentItem().text() == MY_ISSUES_ITEM_NAME: self.save_filter_btn.hide() self.overwrite_filter_button.hide() self.filter_edited_label.hide() self.delete_filter_btn.hide() elif self.filters_list.currentItem().text() == SEARCH_ITEM_NAME.capitalize(): # activate save button self.overwrite_filter_button.hide() self.save_filter_btn.show() self.delete_filter_btn.hide() else: # activate overwrite button self.overwrite_filter_button.show() self.overwrite_filter_button.setEnabled(False) self.save_filter_btn.hide() self.delete_filter_btn.show() def toggle_frame_filters(self): if self.toggle_frame_filters_btn.text() == '<': self.toggle_frame_filters_btn.setText('>') self.filters_frame.hide() else: self.toggle_frame_filters_btn.setText('<') self.filters_frame.show() def add_filter_btn_click(self): self.overwrite_filter_button.hide() self.save_filter_btn.show() self.delete_filter_btn.hide() self.filter_edited_label.hide() self.filters_list.setCurrentItem(None) self.query_field.setText('') self.filter_name_label.setText('Add new filter') self.controller.current_issues.clear() self.show_no_issues() def eventFilter(self, obj, event): # if user started typing in filter field if obj is self.query_field and event.type() == QEvent.KeyRelease: if not self.filters_list.currentItem(): return super().eventFilter(obj, event) current_filter_name = self.filters_list.currentItem().text().lower() # if current filter is not 'Search issues' or 'my open issues' if current_filter_name not in (SEARCH_ITEM_NAME, MY_ISSUES_ITEM_NAME): # if query of current filter has not changed if self.controller.filters_handler.get_filter_by_name( current_filter_name ) != self.query_field.text(): # show that filter has been edited self.filter_edited_label.show() self.overwrite_filter_button.setEnabled(True) else: self.filter_edited_label.hide() self.overwrite_filter_button.setEnabled(False) return super().eventFilter(obj, event) def set_current_filter(self, filter_name): items = self.filters_list.findItems( filter_name, Qt.MatchExactly ) self.filters_list.setCurrentItem(items[0]) self.on_filter_selected(items[0]) def add_filter(self, filter_name): self.filters_list.addItem(filter_name) self.set_current_filter(filter_name) def delete_filter(self): filter_name = self.filters_list.currentItem().text() reply = QMessageBox.question( self, 'Delete filter', "Are you sure you want to delete " "'{}' filter?".format(filter_name), QMessageBox.Yes | QMessageBox.Cancel ) if reply == QMessageBox.Yes: self.controller.filters_handler.delete_filter(filter_name) self.filters_list.takeItem( self.filters_list.currentRow() ) self.filters_list.setCurrentItem( self.filters_list.findItems( MY_ISSUES_ITEM_NAME, Qt.MatchExactly )[0]) self.on_filter_selected(self.filters_list.currentItem()) def show_no_issues(self, error_text=None): self.issue_list_widget.clear() self.issue_list_widget.hide() if error_text: self.label_info.setText(error_text) self.label_info.show() def set_workflow_current_state(self, issue_key): item = self.issue_list_widget.findItems( issue_key, Qt.MatchExactly )[0] custom_item = self.issue_list_widget.itemWidget(item) custom_item.set_workflow.setCurrentIndex(0) def wheelEvent(self, event): # top left corner coordinates of the issue list list_pos = self.issue_list_widget.pos() # check if cursor position is on the issue list if event.pos().x() >= list_pos.x() and event.pos().y() >= list_pos.y(): if event.angleDelta().y() < 0: self.controller.refresh_issue_list(True) event.accept() def closeEvent(self, event): event.ignore() self.hide()
class HomeScreen(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("Home") self.dbOperation = DBOperation() widget = QWidget() widget.setStyleSheet("background:#000") layout_horizontal = QHBoxLayout() menu_vertical_layout = QVBoxLayout() self.btn_home = QPushButton("Home") self.btn_add = QPushButton("Add Vehicle") self.btn_manage = QPushButton("Manage Vehicle") self.btn_history = QPushButton("History") menu_vertical_layout.setContentsMargins(0, 0, 0, 0) menu_vertical_layout.setSpacing(0) self.btn_home.setStyleSheet( "width:200px;height:160px;font-size:20px;background:blue;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_add.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_manage.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_history.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_home.clicked.connect(self.showHome) self.btn_add.clicked.connect(self.showAdd) self.btn_manage.clicked.connect(self.showManage) self.btn_history.clicked.connect(self.showHistory) menu_frame = QFrame() menu_vertical_layout.addWidget(self.btn_home) menu_vertical_layout.addWidget(self.btn_add) menu_vertical_layout.addWidget(self.btn_manage) menu_vertical_layout.addWidget(self.btn_history) menu_vertical_layout.addStretch() menu_frame.setLayout(menu_vertical_layout) #menu_frame.setMinimumWidth(200) #menu_frame.setMaximumHeight(200) parent_vertical = QVBoxLayout() parent_vertical.setContentsMargins(0, 0, 0, 0) self.vertical_1 = QVBoxLayout() self.addHomePageData() self.vertical_2 = QVBoxLayout() self.vertical_2.setContentsMargins(0, 0, 0, 0) self.addAddStudentPage() self.vertical_3 = QVBoxLayout() self.vertical_3.setContentsMargins(0, 0, 0, 0) self.addManagePage() self.vertical_4 = QVBoxLayout() self.addHistoryPage() self.frame_1 = QFrame() self.frame_1.setMinimumWidth(self.width()) self.frame_1.setMaximumWidth(self.width()) self.frame_1.setMaximumHeight(self.width()) self.frame_1.setMaximumHeight(self.width()) self.frame_1.setLayout(self.vertical_1) self.frame_2 = QFrame() self.frame_2.setLayout(self.vertical_2) self.frame_3 = QFrame() self.frame_3.setLayout(self.vertical_3) self.frame_4 = QFrame() self.frame_4.setLayout(self.vertical_4) parent_vertical.addWidget(self.frame_1) parent_vertical.addWidget(self.frame_2) parent_vertical.addWidget(self.frame_3) parent_vertical.addWidget(self.frame_4) layout_horizontal.addWidget(menu_frame) layout_horizontal.addLayout(parent_vertical) layout_horizontal.setContentsMargins(0, 0, 0, 0) parent_vertical.setContentsMargins(0, 0, 0, 0) parent_vertical.addStretch() #menu_vertical_layout.addStretch() layout_horizontal.addStretch() widget.setLayout(layout_horizontal) self.frame_1.show() self.frame_2.hide() self.frame_3.hide() self.frame_4.hide() self.setCentralWidget(widget) def showHistory(self): self.btn_home.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_add.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_manage.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_history.setStyleSheet( "width:200px;height:160px;font-size:20px;background:blue;color:#fff;font-weight:bold;border:1px solid white" ) self.frame_1.hide() self.frame_2.hide() self.frame_3.hide() self.frame_4.show() def showManage(self): self.btn_home.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_add.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_manage.setStyleSheet( "width:200px;height:160px;font-size:20px;background:blue;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_history.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.frame_1.hide() self.frame_2.hide() self.frame_4.hide() self.frame_3.show() def showAdd(self): self.btn_home.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_add.setStyleSheet( "width:200px;height:160px;font-size:20px;background:blue;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_manage.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_history.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.frame_1.hide() self.frame_3.hide() self.frame_4.hide() self.frame_2.show() def showHome(self): self.btn_home.setStyleSheet( "width:200px;height:160px;font-size:20px;background:blue;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_add.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_manage.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.btn_history.setStyleSheet( "width:200px;height:160px;font-size:20px;background:orange;color:#fff;font-weight:bold;border:1px solid white" ) self.frame_2.hide() self.frame_3.hide() self.frame_4.hide() self.frame_1.show() def refreshHome(self): while self.gridLayout.count(): child = self.gridLayout.takeAt(0) if child.widget(): child.widget().deleteLater() row = 0 i = 0 alldata = self.dbOperation.getSlotSpace() for data in alldata: label = QPushButton("Slot " + str(data[0]) + " \n " + str(data[1])) if data[3] == 1: label.setStyleSheet( "background-color:green;color:white;padding:5px;width:100px;height:100px;border:1px solid white;text-align:center;font-weight:bold" ) else: label.setStyleSheet( "background-color:red;color:white;padding:5px;width:100px;height:100px;border:1px solid white;text-align:center;font-weight:bold" ) if i % 5 == 0: i = 0 row = row + 1 self.gridLayout.addWidget(label, row, i) i = i + 1 def addHomePageData(self): self.vertical_1.setContentsMargins(0, 0, 0, 0) button = QPushButton("Refresh") button.clicked.connect(self.refreshHome) vertical_layout = QVBoxLayout() vertical_layout.setContentsMargins(0, 0, 0, 0) frame = QFrame() horizontal = QHBoxLayout() horizontal.setContentsMargins(0, 0, 0, 0) vertical_layout.addLayout(horizontal) alldata = self.dbOperation.getSlotSpace() self.gridLayout = QGridLayout() self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setHorizontalSpacing(0) self.gridLayout.setVerticalSpacing(0) vertical_layout.addWidget(button) vertical_layout.addLayout(self.gridLayout) row = 0 i = 0 for data in alldata: label = QPushButton("Slot " + str(data[0]) + " \n " + str(data[1])) if data[3] == 1: label.setStyleSheet( "background-color:green;color:white;padding:5px;width:100px;height:100px;border:1px solid white;text-align:center;font-weight:bold" ) else: label.setStyleSheet( "background-color:red;color:white;padding:5px;width:100px;height:100px;border:1px solid white;text-align:center;font-weight:bold" ) if i % 5 == 0: i = 0 row = row + 1 self.gridLayout.addWidget(label, row, i) i = i + 1 frame.setLayout(vertical_layout) self.vertical_1.addWidget(frame) self.vertical_1.addStretch() def addAddStudentPage(self): layout = QVBoxLayout() frame = QFrame() name_label = QLabel("Name : ") name_label.setStyleSheet("color:#fff;padding:8px 0px;font-size:20px") mobile_label = QLabel("Mobile : ") mobile_label.setStyleSheet("color:#fff;padding:8px 0px;font-size:20px") vechicle_label = QLabel("Vehicle No : ") vechicle_label.setStyleSheet( "color:#fff;padding:8px 0px;font-size:20px") vechicle_type = QLabel("Vehicle Type : ") vechicle_type.setStyleSheet( "color:#fff;padding:8px 0px;font-size:20px") error_label = QLabel("") error_label.setStyleSheet("color:red;padding:8px 0px;font-size:20px") name_input = QLineEdit() name_input.setStyleSheet("color:#fff;padding:8px 0px;font-size:20px") mobile_input = QLineEdit() mobile_input.setStyleSheet("color:#fff;padding:8px 0px;font-size:20px") vehicle_input = QLineEdit() vehicle_input.setStyleSheet( "color:#fff;padding:8px 0px;font-size:20px") vtype = QComboBox() vtype.setStyleSheet( "color:#fff;padding:8px 0px;font-size:20px;border:1px solid white") vtype.addItem("2 Wheeler") vtype.addItem("4 Wheeler") button = QPushButton("Add Vehicle") button.setStyleSheet( "color:#fff;padding:8px 0px;font-size:20px;background:green;border:1px solid white" ) layout.addWidget(name_label) layout.addWidget(name_input) layout.addWidget(mobile_label) layout.addWidget(mobile_input) layout.addWidget(vechicle_label) layout.addWidget(vehicle_input) layout.addWidget(vechicle_type) layout.addWidget(vtype) layout.addWidget(button) layout.addWidget(error_label) layout.setContentsMargins(0, 0, 0, 0) frame.setMinimumHeight(self.height()) frame.setMinimumWidth(self.width()) frame.setMaximumHeight(self.width()) frame.setMaximumWidth(self.width()) layout.addStretch() frame.setLayout(layout) button.clicked.connect( lambda: self.addVehicles(name_input.text(), vehicle_input.text( ), mobile_input.text(), vtype.currentIndex(), error_label)) self.vertical_2.addWidget(frame) def addVehicles(self, name, vehicleno, mobile, index, error_label): vtp = 2 if index == 0: vtp = 2 else: vtp = 4 data = self.dbOperation.AddVehicles(name, vehicleno, mobile, str(vtp)) if data == True: error_label.setText("Added Successfully") elif data == False: error_label.setText("Failed to Add Vehicle") else: error_label.setText(str(data)) def addManagePage(self): data = self.dbOperation.getCurrentVehicle() self.table = QTableWidget() self.table.setStyleSheet("background:#fff") self.table.resize(self.width(), self.height()) self.table.setRowCount(len(data)) self.table.setColumnCount(7) self.table.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.table.setHorizontalHeaderItem(0, QTableWidgetItem("ID")) self.table.setHorizontalHeaderItem(1, QTableWidgetItem("Name")) self.table.setHorizontalHeaderItem(2, QTableWidgetItem("VEHICLE No")) self.table.setHorizontalHeaderItem(3, QTableWidgetItem("MOBILE")) self.table.setHorizontalHeaderItem(4, QTableWidgetItem("VEHICLE TYPE")) self.table.setHorizontalHeaderItem(5, QTableWidgetItem("ENTRY TIME")) self.table.setHorizontalHeaderItem(6, QTableWidgetItem("ACTION")) loop = 0 for smalldata in data: self.table.setItem(loop, 0, QTableWidgetItem(str(smalldata[0]))) self.table.setItem(loop, 1, QTableWidgetItem(str(smalldata[1]))) self.table.setItem(loop, 2, QTableWidgetItem(str(smalldata[6]))) self.table.setItem(loop, 3, QTableWidgetItem(str(smalldata[2]))) self.table.setItem(loop, 4, QTableWidgetItem(str(smalldata[7]))) self.table.setItem(loop, 5, QTableWidgetItem(str(smalldata[3]))) self.button_exit = QPushButton("Exit") self.button_exit.setStyleSheet( "color:#fff;padding:8px 0px;font-size:20px;background:green;border:1px solid white" ) self.table.setCellWidget(loop, 6, self.button_exit) self.button_exit.clicked.connect(self.exitCall) loop = loop + 1 frame = QFrame() layout = QVBoxLayout() button = QPushButton("Refresh") button.setStyleSheet( "color:#fff;padding:8px 0px;font-size:20px;background:green;border:1px solid white" ) button.clicked.connect(self.refreshManage) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(button) layout.addWidget(self.table) frame.setLayout(layout) frame.setContentsMargins(0, 0, 0, 0) frame.setMaximumWidth(self.width()) frame.setMinimumWidth(self.width()) frame.setMaximumHeight(self.height()) frame.setMinimumHeight(self.height()) self.vertical_3.addWidget(frame) self.vertical_3.addStretch() def refreshManage(self): data = self.dbOperation.getCurrentVehicle() self.table.setRowCount(len(data)) self.table.setColumnCount(7) loop = 0 for smalldata in data: self.table.setItem(loop, 0, QTableWidgetItem(str(smalldata[0]))) self.table.setItem(loop, 1, QTableWidgetItem(str(smalldata[1]))) self.table.setItem(loop, 2, QTableWidgetItem(str(smalldata[6]))) self.table.setItem(loop, 3, QTableWidgetItem(str(smalldata[2]))) self.table.setItem(loop, 4, QTableWidgetItem(str(smalldata[7]))) self.table.setItem(loop, 5, QTableWidgetItem(str(smalldata[3]))) self.button_exit = QPushButton("Exit") self.table.setCellWidget(loop, 6, self.button_exit) self.button_exit.clicked.connect(self.exitCall) loop = loop + 1 def refreshHistory(self): self.table1.clearContents() data = self.dbOperation.getAllVehicle() loop = 0 self.table1.setRowCount(len(data)) self.table1.setColumnCount(7) for smalldata in data: self.table1.setItem(loop, 0, QTableWidgetItem(str(smalldata[0]))) self.table1.setItem(loop, 1, QTableWidgetItem(str(smalldata[1]))) self.table1.setItem(loop, 2, QTableWidgetItem(str(smalldata[6]))) self.table1.setItem(loop, 3, QTableWidgetItem(str(smalldata[2]))) self.table1.setItem(loop, 4, QTableWidgetItem(str(smalldata[7]))) self.table1.setItem(loop, 5, QTableWidgetItem(str(smalldata[3]))) self.table1.setItem(loop, 6, QTableWidgetItem(str(smalldata[4]))) loop = loop + 1 def addHistoryPage(self): data = self.dbOperation.getAllVehicle() self.table1 = QTableWidget() self.table1.resize(self.width(), self.height()) self.table1.setRowCount(len(data)) self.table1.setStyleSheet("background:#fff") self.table1.setColumnCount(7) button = QPushButton("Refresh") button.setStyleSheet( "color:#fff;padding:8px 0px;font-size:20px;background:green;border:1px solid white" ) button.clicked.connect(self.refreshHistory) self.table1.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.table1.setHorizontalHeaderItem(0, QTableWidgetItem("ID")) self.table1.setHorizontalHeaderItem(1, QTableWidgetItem("Name")) self.table1.setHorizontalHeaderItem(2, QTableWidgetItem("VEHICLE No")) self.table1.setHorizontalHeaderItem(3, QTableWidgetItem("MOBILE")) self.table1.setHorizontalHeaderItem(4, QTableWidgetItem("VEHICLE TYPE")) self.table1.setHorizontalHeaderItem(5, QTableWidgetItem("ENTRY TIME")) self.table1.setHorizontalHeaderItem(6, QTableWidgetItem("EXIT TIME")) loop = 0 for smalldata in data: self.table1.setItem(loop, 0, QTableWidgetItem(str(smalldata[0]))) self.table1.setItem(loop, 1, QTableWidgetItem(str(smalldata[1]))) self.table1.setItem(loop, 2, QTableWidgetItem(str(smalldata[6]))) self.table1.setItem(loop, 3, QTableWidgetItem(str(smalldata[2]))) self.table1.setItem(loop, 4, QTableWidgetItem(str(smalldata[7]))) self.table1.setItem(loop, 5, QTableWidgetItem(str(smalldata[3]))) self.table1.setItem(loop, 6, QTableWidgetItem(str(smalldata[4]))) loop = loop + 1 self.frame5 = QFrame() self.layout1 = QVBoxLayout() self.layout1.setContentsMargins(0, 0, 0, 0) self.layout1.setSpacing(0) self.layout1.addWidget(button) self.layout1.addWidget(self.table1) self.frame5.setLayout(self.layout1) self.frame5.setContentsMargins(0, 0, 0, 0) self.frame5.setMaximumWidth(self.width()) self.frame5.setMinimumWidth(self.width()) self.frame5.setMaximumHeight(self.height()) self.frame5.setMinimumHeight(self.height()) self.vertical_4.addWidget(self.frame5) self.vertical_4.addStretch() def exitCall(self): btton = self.sender() if btton: row = self.table.indexAt(btton.pos()).row() id = str(self.table.item(row, 0).text()) self.dbOperation.exitVehicle(id) self.table.removeRow(row)
class RightForm1(QFrame): """ 右侧框体1 """ def __init__(self): super(RightForm1, self).__init__() self.init() self.setup_ui() self.set_form_layout() def init(self): pass def setup_ui(self): # ***************左侧****************** self.loadingFrame = QFrame() self.loadingFrame.setObjectName('loadingFrame') self.loadingFrame.setFrameShape(QFrame.StyledPanel) # 最小化以及设置按钮管理栏 self.loadingFrameBar = QWidget(self.loadingFrame) self.loadingFrameBar.setObjectName('loadingFrameBar') self.loadingFrameBar.resize(self.loadingFrame.width(), 20) self.loadingFrameSettingBtn = QPushButton(self.loadingFrameBar) self.loadingFrameSettingBtn.setIcon( QIcon('./image/mainWindowIcon/RightForm1Image/setting.png')) self.loadingFrameSettingBtn.setMaximumWidth(30) self.loadingFrameMinBtn = QPushButton(self.loadingFrameBar) self.loadingFrameMinBtn.setIcon( QIcon('./image/mainWindowIcon/RightForm1Image/min.png')) self.loadingFrameMinBtn.setMaximumWidth(30) self.loadingFrameMinBtn.clicked.connect(lambda: self.hide_loadframe()) # 选项卡面板 self.loadingTab = QTabWidget(self.loadingFrame) self.loadingTab.setObjectName('loadingTab') # *********图片加载模式UI设计********** self.imageLoadingForm = QWidget(self.loadingTab) self.imageLoadingForm.setObjectName('imageLoadingForm') self.form1_a = QWidget(self.imageLoadingForm) self.form1_a.setObjectName('form1_a') self.groupBox1 = QGroupBox(self.form1_a) self.groupBox1.setObjectName('groupBox1') self.groupBox1.setTitle('图片显示:') self.graphicsView = QGraphicsView(self.groupBox1) self.graphicsView.setObjectName('graphicsView') # 显示图片信息框 self.textEdit1 = QTextEdit(self.form1_a) self.textEdit1.setObjectName('textEdit1') self.textEdit1.setReadOnly(True) self.textEdit1.setText('当前还没加载图片,' + '\n' + '无法查看图片信息!!!') self.form2_a = QWidget(self.imageLoadingForm) self.form2_a.setObjectName('form2_a') self.groupBox2 = QGroupBox(self.form2_a) self.groupBox2.setObjectName('groupBox2') self.groupBox2.setTitle('图片列表') # 加载图片列表 self.imageListWidget = QListWidget(self.form2_a) self.imageListWidget.setObjectName('imageListWidget') self.imageListWidget.setToolTip('图片加载列表') self.imageListWidget.setMinimumWidth(600) self.buttonWidget = QWidget() self.buttonWidget.setObjectName('buttonWidget') self.imageOpenBtn = QPushButton('打开图片') self.imageOpenBtn.setObjectName('imageOpenBtn') self.imageOpenBtn.clicked.connect(lambda: self.load_image()) # 图片选择改变事件监听 self.imageListWidget.currentRowChanged.connect( lambda: self.image_selecttion_change(self.imageListWidget. currentItem().text())) self.imageListWidget.currentItemChanged.connect( lambda: self.display_image_message(self.imageListWidget. currentItem().text())) # 工具栏 self.imageToolFrame = QFrame(self.form2_a) self.imageToolFrame.setObjectName('imageToolFrame') self.imageToolFrame.setFrameShape(QFrame.StyledPanel) # 开始识别按钮 self.startIdentifyBtn = QPushButton('开始识别') self.startIdentifyBtn.setObjectName('startIdentifyBtn') # ###################################################### # **********文档加载模式UI设计*********** self.textLoadingForm = QWidget(self.loadingFrame) # self.textLoadingForm.setObjectName('textLoadingForm') # # self.form1_b = QWidget(self.textLoadingForm) # self.form1_b.setObjectName('form1_b') # # 显示文档信息框 # self.textEdit2 = QTextEdit(self.form1_b) # self.textEdit2.setObjectName('textEdit2') # # # 工具栏 # self.toolWidget2 = QWidget() # self.toolWidget2.setObjectName('toolWidget2') # self.textOpenBtn = QPushButton('打开文档') # self.textOpenBtn.setObjectName('textOpenBtn') # ############################################################################ # # ***************右侧****************** self.resultFrame = QFrame() self.resultFrame.setObjectName('resultFrame') self.resultFrame.setFrameShape(QFrame.StyledPanel) # 最小化以及设置按钮管理栏 self.resultFrameBar = QWidget() self.resultFrameBar.setObjectName('resultFrameBar') self.resultFrameBar.resize(self.resultFrame.width(), 20) self.resultFrameSettingBtn = QPushButton(self.loadingFrameBar) self.resultFrameSettingBtn.setObjectName('resultFrameSettingBtn') self.resultFrameSettingBtn.setIcon( QIcon('./image/mainWindowIcon/RightForm1Image/setting.png')) self.resultFrameSettingBtn.setMaximumWidth(30) self.resultFrameMinBtn = QPushButton(self.loadingFrameBar) self.resultFrameMinBtn.setIcon( QIcon('./image/mainWindowIcon/RightForm1Image/min.png')) self.resultFrameMinBtn.setMaximumWidth(30) self.resultFrameMinBtn.clicked.connect(lambda: self.hide_resultframe()) self.resultEdit = QTextEdit() self.resultEdit.setObjectName('resultEdit') # ########################################################################### # 分隔符部件 self.mainSplitter = QSplitter(Qt.Horizontal) self.mainSplitter.setObjectName('mainSplitter') def set_form_layout(self): # 主框体总布局 self.allLayout = QHBoxLayout() self.setLayout(self.allLayout) self.allLayout.addWidget(self.mainSplitter) self.mainSplitter.addWidget(self.loadingFrame) self.mainSplitter.addWidget(self.resultFrame) # 左侧布局 self.loadingFrameLayout = QGridLayout() self.loadingFrame.setLayout(self.loadingFrameLayout) self.loadingFrameLayout.addWidget(self.loadingFrameBar, 0, 0) self.loadingFrameLayout.addWidget(self.loadingTab, 1, 0) # ******************加载图片模式******************** self.imageLoadingFormLayout = QGridLayout() self.imageLoadingForm.setLayout(self.imageLoadingFormLayout) self.imageLoadingFormLayout.addWidget(self.form1_a, 0, 0, 3, 1) self.imageLoadingFormLayout.addWidget(self.form2_a, 3, 0, 2, 1) self.loadingFrameBarLayout = QHBoxLayout() self.loadingFrameBar.setLayout(self.loadingFrameBarLayout) self.loadingFrameBarLayout.setAlignment(Qt.AlignRight) self.loadingFrameBarLayout.addWidget(self.loadingFrameSettingBtn) self.loadingFrameBarLayout.addWidget(self.loadingFrameMinBtn) self.form1Layout = QHBoxLayout() self.form1_a.setLayout(self.form1Layout) self.form1Layout.addWidget(self.groupBox1, 3) self.form1Layout.addWidget(self.textEdit1, 1) self.qHBoxLayout = QHBoxLayout() self.groupBox1.setLayout(self.qHBoxLayout) self.qHBoxLayout.addWidget(self.graphicsView) self.form2Layout = QGridLayout() self.form2_a.setLayout(self.form2Layout) self.form2Layout.addWidget(self.groupBox2, 0, 0, 1, 3) self.form2Layout.addWidget(self.imageToolFrame, 0, 4) self.groupBox2Layout = QHBoxLayout() self.groupBox2.setLayout(self.groupBox2Layout) self.groupBox2Layout.addWidget(self.imageListWidget) self.groupBox2Layout.addWidget(self.buttonWidget) self.buttonWidgetLayout = QGridLayout() self.buttonWidget.setLayout(self.buttonWidgetLayout) self.buttonWidgetLayout.addWidget(self.imageOpenBtn) self.imageToolFrameLayout = QVBoxLayout() self.imageToolFrame.setLayout(self.imageToolFrameLayout) self.imageToolFrameLayout.addWidget(self.startIdentifyBtn) # ******************加载文档模式******************** self.loadingTab.addTab(self.imageLoadingForm, '图片加载智能识别 ') self.loadingTab.addTab(self.textLoadingForm, '文档加载智能识别') # 右侧布局 self.resultFrameBarLayout = QHBoxLayout() self.resultFrameBar.setLayout(self.resultFrameBarLayout) self.resultFrameBarLayout.setAlignment(Qt.AlignRight) self.resultFrameBarLayout.addWidget(self.resultFrameSettingBtn) self.resultFrameBarLayout.addWidget(self.resultFrameMinBtn) self.resultFrameLayout = QGridLayout() self.resultFrame.setLayout(self.resultFrameLayout) self.resultFrameLayout.addWidget(self.resultFrameBar) self.resultFrameLayout.addWidget(self.resultEdit) # ******************************业务逻辑********************************** def load_image(self): """ 将图片加载到图片列表 :return: """ image_path, image_type = QFileDialog.getOpenFileName( self, '选择图片', 'c:\\', 'Image files(*.jpg *.gif *.png)') # 增加图片目录 self.imageListWidget.addItem(image_path) # 显示图片 self.display_image(image_path) # self.display_image_message(image_path) def display_image(self, image_path): """ 显示图片 :param image_path: :return: """ self.image_path = image_path self.image = QPixmap() self.image.load(self.image_path) self.graphicsView.scene = QGraphicsScene() item = QGraphicsPixmapItem(self.image) self.graphicsView.scene.addItem(item) self.graphicsView.setScene(self.graphicsView.scene) def image_selecttion_change(self, current_path): self.current_path = current_path self.display_image(self.current_path) # self.display_image_message(self.current_path) def display_image_message(self, image_path): message = '' self.image_path = image_path message = self.load_image_message(self.image_path) self.textEdit1.setText(message) def load_image_message(self, image_path): """ 会返回一个字典,包含图像的各种属性信息 :param image_path: :return: """ self.image_path = image_path message = '' image = Image.open(self.image_path) # 还没有完成************** return message def load_text(self): pass def hide_loadframe(self): self.loadingFrame.hide() def hide_resultframe(self): self.resultFrame.hide()
class AudioVideoTab(QWidget): def __init__(self, parent): super(AudioVideoTab, self).__init__(parent) self.parent = parent self.name = 'AudioVideo' self.defaultStr = self.tr('Default') self.DisableStream = self.tr('Disable') self.formats = config.video_formats frequency_values = [self.defaultStr] + config.video_frequency_values bitrate_values = [self.defaultStr] + config.video_bitrate_values rotation_options = [ self.tr('None'), '90 ' + self.tr('clockwise'), '90 ' + self.tr('clockwise') + ' + ' + self.tr('vertical flip'), '90 ' + self.tr('counter clockwise'), '90 ' + self.tr('counter clockwise') + ' + ' + self.tr('vertical flip'), '180', self.tr('horizontal flip'), self.tr('vertical flip') ] digits_validator = QRegExpValidator(QRegExp(r'[1-9]\d*'), self) digits_validator_wzero = QRegExpValidator(QRegExp(r'\d*'), self) digits_validator_minus = QRegExpValidator(QRegExp(r'(-1|[1-9]\d*)'), self) time_validator = QRegExpValidator( QRegExp(r'\d{1,2}:\d{1,2}:\d{1,2}\.\d+'), self) converttoQL = QLabel(self.tr('Convert to:')) self.extQCB = QComboBox() self.extQCB.setMinimumWidth(100) vidcodecQL = QLabel('Video codec:') self.vidcodecQCB = QComboBox() self.vidcodecQCB.setMinimumWidth(110) audcodecQL = QLabel('Audio codec:') self.audcodecQCB = QComboBox() self.audcodecQCB.setMinimumWidth(110) hlayout1 = utils.add_to_layout( 'h', converttoQL, self.extQCB, QSpacerItem(180, 20), vidcodecQL, self.vidcodecQCB, audcodecQL, self.audcodecQCB) commandQL = QLabel(self.tr('Command:')) self.commandQLE = QLineEdit() self.presetQPB = QPushButton(self.tr('Preset')) self.defaultQPB = QPushButton(self.defaultStr) hlayout2 = utils.add_to_layout( 'h', commandQL, self.commandQLE, self.presetQPB, self.defaultQPB) sizeQL = QLabel(self.tr('Video Size:')) aspectQL = QLabel(self.tr('Aspect:')) frameQL = QLabel(self.tr('Frame Rate (fps):')) bitrateQL = QLabel(self.tr('Video Bitrate (kbps):')) self.widthQLE = utils.create_LineEdit( (70, 16777215), digits_validator_minus, 4) self.heightQLE = utils.create_LineEdit( (70, 16777215), digits_validator_minus, 4) label = QLabel('<html><p align="center">x</p></html>') layout1 = utils.add_to_layout('h', self.widthQLE, label,self.heightQLE) self.aspect1QLE = utils.create_LineEdit( (50, 16777215), digits_validator, 2) self.aspect2QLE = utils.create_LineEdit( (50, 16777215), digits_validator, 2) label = QLabel('<html><p align="center">:</p></html>') layout2 = utils.add_to_layout( 'h', self.aspect1QLE, label, self.aspect2QLE) self.frameQLE = utils.create_LineEdit( (120, 16777215), digits_validator, 4) self.bitrateQLE = utils.create_LineEdit( (130, 16777215), digits_validator, 6) labels = [sizeQL, aspectQL, frameQL, bitrateQL] widgets = [layout1, layout2, self.frameQLE, self.bitrateQLE] self.preserveaspectQChB = QCheckBox(self.tr("Preserve aspect ratio")) self.preservesizeQChB = QCheckBox(self.tr("Preserve video size")) preserve_layout = utils.add_to_layout( 'v', self.preserveaspectQChB, self.preservesizeQChB) videosettings_layout = QHBoxLayout() for a, b in zip(labels, widgets): a.setText('<html><p align="center">{0}</p></html>'.format(a.text())) layout = utils.add_to_layout('v', a, b) videosettings_layout.addLayout(layout) if a == aspectQL: # add vidaspectCB in layout after aspectQL videosettings_layout.addLayout(preserve_layout) freqQL = QLabel(self.tr('Frequency (Hz):')) chanQL = QLabel(self.tr('Audio Channels:')) bitrateQL = QLabel(self.tr('Audio Bitrate (kbps):')) threadsQL = QLabel(self.tr('Threads:')) self.freqQCB = QComboBox() self.freqQCB.addItems(frequency_values) self.chan1QRB = QRadioButton('1') self.chan1QRB.setMaximumSize(QSize(51, 16777215)) self.chan2QRB = QRadioButton('2') self.chan2QRB.setMaximumSize(QSize(51, 16777215)) self.group = QButtonGroup() self.group.addButton(self.chan1QRB) self.group.addButton(self.chan2QRB) spcr1 = QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Minimum) spcr2 = QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Minimum) chanlayout = utils.add_to_layout( 'h', spcr1, self.chan1QRB, self.chan2QRB, spcr2) self.audbitrateQCB = QComboBox() self.audbitrateQCB.addItems(bitrate_values) self.threadsQLE = utils.create_LineEdit( (50, 16777215), digits_validator_wzero, 1) labels = [freqQL, bitrateQL, chanQL, threadsQL] widgets = [self.freqQCB, self.audbitrateQCB, chanlayout,self.threadsQLE] audiosettings_layout = QHBoxLayout() for a, b in zip(labels, widgets): a.setText('<html><p align="center">{0}</p></html>'.format(a.text())) layout = utils.add_to_layout('v', a, b) audiosettings_layout.addLayout(layout) time_format = " (hh:mm:ss):" beginQL = QLabel(self.tr("Split file. Begin time") + time_format) self.beginQLE = utils.create_LineEdit(None, time_validator, None) durationQL = QLabel(self.tr("Duration") + time_format) self.durationQLE = utils.create_LineEdit(None, time_validator, None) hlayout4 = utils.add_to_layout( 'h', beginQL, self.beginQLE, durationQL, self.durationQLE) embedQL = QLabel(self.tr("Embed subtitle:")) self.embedQLE = QLineEdit() self.embedQTB = QToolButton() self.embedQTB.setText("...") rotateQL = QLabel(self.tr("Rotate:")) self.rotateQCB = QComboBox() self.rotateQCB.addItems(rotation_options) hlayout5 = utils.add_to_layout( 'h', rotateQL, self.rotateQCB, embedQL, self.embedQLE, self.embedQTB) hidden_layout = utils.add_to_layout( 'v', videosettings_layout, audiosettings_layout, hlayout4, hlayout5) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.moreQPB = QPushButton(QApplication.translate('Tab', 'More')) self.moreQPB.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.moreQPB.setCheckable(True) hlayout3 = utils.add_to_layout('h', line, self.moreQPB) self.frame = QFrame() self.frame.setLayout(hidden_layout) self.frame.hide() final_layout = utils.add_to_layout( 'v', hlayout1, hlayout2, hlayout3, self.frame) self.setLayout(final_layout) self.presetQPB.clicked.connect(self.choose_preset) self.defaultQPB.clicked.connect(self.set_default_command) self.embedQTB.clicked.connect(self.open_subtitle_file) self.moreQPB.toggled.connect(self.frame.setVisible) self.moreQPB.toggled.connect( lambda: QTimer.singleShot(100, self.resize_parent)) self.widthQLE.textChanged.connect(self.command_update_size) self.heightQLE.textChanged.connect(self.command_update_size) self.aspect1QLE.textChanged.connect(self.command_update_aspect) self.aspect2QLE.textChanged.connect(self.command_update_aspect) self.frameQLE.textChanged.connect(self.command_update_frames) self.bitrateQLE.textChanged.connect(self.command_update_vidbitrate) self.threadsQLE.textChanged.connect(self.command_update_threads) self.beginQLE.textChanged.connect(self.command_update_begin_time) self.durationQLE.textChanged.connect(self.command_update_duration) self.embedQLE.textChanged.connect(self.command_update_subtitles) self.vidcodecQCB.currentIndexChanged.connect(self.command_update_vcodec) self.audcodecQCB.currentIndexChanged.connect(self.command_update_acodec) self.freqQCB.currentIndexChanged.connect(self.command_update_frequency) self.rotateQCB.currentIndexChanged.connect(self.command_update_rotation) self.audbitrateQCB.currentIndexChanged.connect( self.command_update_audbitrate) self.chan1QRB.clicked.connect( lambda: self.command_update_channels('1')) self.chan2QRB.clicked.connect( lambda: self.command_update_channels('2')) self.preserveaspectQChB.toggled.connect( self.command_update_preserve_aspect) self.preservesizeQChB.toggled.connect( self.command_update_preserve_size) def resize_parent(self): """Give MainWindow its default size.""" self.parent.setMinimumSize(self.parent.sizeHint()) self.parent.resize(self.parent.sizeHint()) def clear(self): """Clear all values of graphical widgets.""" lines = [ self.commandQLE, self.widthQLE, self.heightQLE, self.aspect1QLE, self.aspect2QLE, self.frameQLE, self.bitrateQLE, self.threadsQLE, self.beginQLE, self.embedQLE, self.durationQLE ] for i in lines: i.clear() self.vidcodecQCB.setCurrentIndex(0) self.audcodecQCB.setCurrentIndex(0) self.freqQCB.setCurrentIndex(0) self.audbitrateQCB.setCurrentIndex(0) self.rotateQCB.setCurrentIndex(0) self.preserveaspectQChB.setChecked(False) self.preservesizeQChB.setChecked(False) self.group.setExclusive(False) self.chan1QRB.setChecked(False) self.chan2QRB.setChecked(False) self.group.setExclusive(True) # setExclusive(False) in order to be able to uncheck checkboxes and # then setExclusive(True) so only one radio button can be set def fill_video_comboboxes(self, vcodecs, acodecs, extraformats): self.vidcodecQCB.currentIndexChanged.disconnect() self.audcodecQCB.currentIndexChanged.disconnect() self.vidcodecQCB.clear() self.audcodecQCB.clear() self.extQCB.clear() self.vidcodecQCB.addItems([self.defaultStr, self.DisableStream] + vcodecs) self.audcodecQCB.addItems([self.defaultStr, self.DisableStream] + acodecs) self.extQCB.addItems(sorted(self.formats + extraformats)) self.vidcodecQCB.currentIndexChanged.connect(self.command_update_vcodec) self.audcodecQCB.currentIndexChanged.connect(self.command_update_acodec) def ok_to_continue(self): """ Check if everything is ok with audiovideotab to continue conversion. Returns boolean. """ if not self.parent.ffmpeg_path: QMessageBox.warning(self, 'FF Multi Converter - ' + self.tr( 'Error!'), self.tr('FFmpeg is not installed!')) return False return True def open_subtitle_file(self): fname = QFileDialog.getOpenFileName( self, 'FF Multi Converter - ' + self.tr('Choose File'), config.home, 'Subtitles (*.srt *.sub *.ssa *.ass)' )[0] if fname: self.embedQLE.setText(fname) def set_default_command(self): """Set the default value to self.commandQLE.""" self.clear() self.commandQLE.setText(self.parent.default_command) def choose_preset(self): """ Open the presets dialog and update self.commandQLE, and self.extQCB and with the appropriate values. """ dialog = presets_dlgs.ShowPresets(choose=True) if dialog.exec_() and dialog.the_command is not None: self.clear() self.commandQLE.setText(dialog.the_command) self.commandQLE.home(False) find = self.extQCB.findText(dialog.the_extension) if find >= 0: self.extQCB.setCurrentIndex(find) def command_update_size(self): command = self.commandQLE.text() text1 = self.widthQLE.text() text2 = self.heightQLE.text() if not (text1 == '-1' or text2 == '-1'): self.preserveaspectQChB.setChecked(False) if (text1 or text2) and not (text1 and text2) or (text1 == '-' or text2 == '-'): return regex = r'(\s+|^)-s(:v){0,1}\s+\d+x\d+(\s+|$)' if re.search(regex, command): command = re.sub(regex, '', command) regex = r'(,*\s*){0,1}(scale=-?\d+:-?\d+)(\s*,*\s*){0,1}' _filter = "scale={0}:{1}".format(text1, text2) if text1 and text2 else '' self.commandQLE.setText(utils.update_cmdline_text( command, _filter, regex, bool(text1 and text2), 0, 2)) def command_update_preserve_size(self): checked = self.preservesizeQChB.isChecked() self.widthQLE.setEnabled(not checked) self.heightQLE.setEnabled(not checked) if checked: self.widthQLE.clear() self.heightQLE.clear() # command_update_size() is triggered here command = self.commandQLE.text() regex = r'(\s+|^)-s\s+\d+x\d+(\s+|$)' command = re.sub(' +', ' ', re.sub(regex, ' ', command)).strip() self.commandQLE.setText(command) def command_update_aspect(self): command = self.commandQLE.text() text1 = self.aspect1QLE.text() text2 = self.aspect2QLE.text() if (text1 or text2) and not (text1 and text2): return regex = r'(\s+|^)-aspect\s+\d+:\d+(\s+|$)' s = ' -aspect {0}:{1} '.format(text1, text2) if text1 and text2 else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_preserve_aspect(self): command = self.commandQLE.text() checked = self.preserveaspectQChB.isChecked() self.aspect1QLE.setEnabled(not checked) self.aspect2QLE.setEnabled(not checked) if checked: self.aspect1QLE.clear() self.aspect2QLE.clear() # self.command_update_aspect() is triggered here regex = r'(,*\s*){0,1}(scale=(-?\d+):(-?\d+))(\s*,*\s*){0,1}' search = re.search(regex, command) if search: width = search.groups()[2] height = search.groups()[3] if not (width == '-1' or height == '-1'): s = "scale=-1:{0}".format(height) command = re.sub(regex, r'\1{0}\5'.format(s), command) self.widthQLE.setText('-1') self.heightQLE.setText(height) regex = r'(\s+|^)-aspect\s+\d+:\d+(\s+|$)' command = re.sub(' +', ' ', re.sub(regex, ' ', command)).strip() self.commandQLE.setText(command) def command_update_frames(self): command = self.commandQLE.text() text = self.frameQLE.text() regex = r'(\s+|^)-r\s+\d+(\s+|$)' s = ' -r {0} '.format(text) if text else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_vidbitrate(self): command = self.commandQLE.text() text = self.bitrateQLE.text() regex = r'(\s+|^)-b(:v){0,1}\s+\d+[kKmM](\s+|$)' s = ' -b:v {0}k '.format(text) if text else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub('-sameq', '', command) command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_frequency(self): command = self.commandQLE.text() text = self.freqQCB.currentText() regex = r'(\s+|^)-ar\s+\d+(\s+|$)' s = ' -ar {0} '.format(text) if self.freqQCB.currentIndex() != 0 else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_audbitrate(self): command = self.commandQLE.text() text = self.audbitrateQCB.currentText() regex = r'(\s+|^)-(ab|b:a)\s+\d+[kKmM](\s+|$)' if self.audbitrateQCB.currentIndex() != 0: s = ' -b:a {0}k '.format(text) else: s = ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_channels(self, channel): command = self.commandQLE.text() regex = r'(\s+|^)-ac\s+\d+(\s+|$)' s = ' -ac {0} '.format(channel) if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_threads(self): command = self.commandQLE.text() text = self.threadsQLE.text() regex = r'(\s+|^)-threads\s+\d+(\s+|$)' s = ' -threads {0} '.format(text) if text else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_begin_time(self): command = self.commandQLE.text() text = self.beginQLE.text() regex = r'(\s+|^)-ss\s+\S+(\s+|$)' s = ' -ss {0} '.format(text) if text else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_duration(self): command = self.commandQLE.text() text = self.durationQLE.text() regex = r'(\s+|^)-t\s+\S+(\s+|$)' s = ' -t {0} '.format(text) if text else ' ' if re.search(regex, command): command = re.sub(regex, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_vcodec(self): command = self.commandQLE.text() text = self.vidcodecQCB.currentText() regex = r'(\s+|^)-(vcodec|c:v)\s+\S+(\s+|$)' regex_vn = r'(\s+|^)-vn(\s+|$)' if self.vidcodecQCB.currentIndex() == 1: s = ' -vn '.format(text) elif self.vidcodecQCB.currentIndex() == 0: s = ' ' else: s = ' -vcodec {0} '.format(text) if re.search(regex, command): command = re.sub(regex, s, command) elif re.search(regex_vn, command): command = re.sub(regex_vn, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_acodec(self): command = self.commandQLE.text() text = self.audcodecQCB.currentText() regex = r'(\s+|^)-(acodec|c:a)\s+\S+(\s+|$)' regex_an = r'(\s+|^)-an(\s+|$)' if self.audcodecQCB.currentIndex() == 1: s = ' -an '.format(text) elif self.audcodecQCB.currentIndex() == 0: s = ' ' else: s = ' -acodec {0} '.format(text) if re.search(regex, command): command = re.sub(regex, s, command) elif re.search(regex_an, command): command = re.sub(regex_an, s, command) else: command += s command = re.sub(' +', ' ', command).strip() self.commandQLE.setText(command) def command_update_subtitles(self): command = self.commandQLE.text() regex = r'(,*\s*){0,1}(subtitles=\'.*\')(\s*,*\s*){0,1}' text = self.embedQLE.text() _filter = "subtitles='{0}'".format(text) if text else '' self.commandQLE.setText(utils.update_cmdline_text( command, _filter, regex, bool(text), 0, 2)) def command_update_rotation(self): command = self.commandQLE.text() regex = r'(,*\s*){0,1}(transpose=\d(,\s*transpose=\d)*|vflip|hflip)(\s*,*\s*){0,1}' rotate = self.rotateQCB.currentIndex() if rotate == 0: # none _filter = '' elif rotate == 1: # 90 clockwise _filter = 'transpose=1' elif rotate == 2: # 90 clockwise + vertical flip _filter = 'transpose=3' elif rotate == 3: # 90 counter clockwise _filter = 'transpose=2' elif rotate == 4: # 90 counter clockwise + vertical flip _filter = 'transpose=0' elif rotate == 5: # 180 _filter = 'transpose=2,transpose=2' elif rotate == 6: # horizontal flip _filter = 'hflip' elif rotate == 7: # vertical flip _filter = 'vflip' self.commandQLE.setText(utils.update_cmdline_text( command, _filter, regex, bool(rotate != 0), 0, 3))
class GcodeEditor(QWidget, _HalWidgetBase): percentDone = pyqtSignal(int) def __init__(self, parent=None): super(GcodeEditor, self).__init__(parent) self.load_dialog_code = 'LOAD' self.save_dialog_code = 'SAVE' STATUS.connect('general',self.returnFromDialog) self.isCaseSensitive = 0 self.setMinimumSize(QSize(300, 200)) self.setWindowTitle("PyQt5 editor test example") lay = QVBoxLayout() lay.setContentsMargins(0,0,0,0) self.setLayout(lay) # make editor self.editor = GcodeDisplay(self) # class patch editor's function to ours # so we get the lines percent update self.editor.emit_percent = self.emit_percent self.editor.setReadOnly(True) self.editor.setModified(False) ################################ # add menubar actions ################################ # Create new action newAction = QAction(QIcon.fromTheme('document-new'), 'New', self) newAction.setShortcut('Ctrl+N') newAction.setStatusTip('New document') newAction.triggered.connect(self.newCall) # Create open action openAction = QAction(QIcon.fromTheme('document-open'), '&Open', self) openAction.setShortcut('Ctrl+O') openAction.setStatusTip('Open document') openAction.triggered.connect(self.openCall) # Create save action saveAction = QAction(QIcon.fromTheme('document-save'), '&save', self) saveAction.setShortcut('Ctrl+S') saveAction.setStatusTip('save document') saveAction.triggered.connect(self.saveCall) # Create exit action exitAction = QAction(QIcon.fromTheme('application-exit'), '&Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.exitCall) # Create gcode lexer action gCodeLexerAction = QAction(QIcon.fromTheme('lexer.png'), '&Gcode\n lexer', self) gCodeLexerAction.setCheckable(1) gCodeLexerAction.setShortcut('Ctrl+G') gCodeLexerAction.setStatusTip('Set Gcode highlighting') gCodeLexerAction.triggered.connect(self.gcodeLexerCall) # Create gcode lexer action pythonLexerAction = QAction(QIcon.fromTheme('lexer.png'), '&python\n lexer', self) pythonLexerAction.setShortcut('Ctrl+P') pythonLexerAction.setStatusTip('Set Python highlighting') pythonLexerAction.triggered.connect(self.pythonLexerCall) # Create toolbar and add action toolBar = QToolBar('File') toolBar.addAction(newAction) toolBar.addAction(openAction) toolBar.addAction(saveAction) toolBar.addAction(exitAction) toolBar.addSeparator() # add lexer actions toolBar.addAction(gCodeLexerAction) toolBar.addAction(pythonLexerAction) toolBar.addSeparator() toolBar.addWidget(QLabel('<html><head/><body><p><span style=" font-size:20pt; font-weight:600;">Edit Mode</span></p></body></html>')) # create a frame for buttons box = QHBoxLayout() box.addWidget(toolBar) self.topMenu = QFrame() self.topMenu.setLayout(box) # add widgets lay.addWidget(self.topMenu) lay.addWidget(self.editor) lay.addWidget(self.createGroup()) self.readOnlyMode() def createGroup(self): self.bottomMenu = QFrame() self.searchText = QLineEdit(self) self.replaceText = QLineEdit(self) toolBar = QToolBar() # Create new action undoAction = QAction(QIcon.fromTheme('edit-undo'), 'Undo', self) undoAction.setStatusTip('Undo') undoAction.triggered.connect(self.undoCall) toolBar.addAction(undoAction) # create redo action redoAction = QAction(QIcon.fromTheme('edit-redo'), 'Redo', self) redoAction.setStatusTip('Undo') redoAction.triggered.connect(self.redoCall) toolBar.addAction(redoAction) toolBar.addSeparator() # create replace action replaceAction = QAction(QIcon.fromTheme('edit-find-replace'), 'Replace', self) replaceAction.triggered.connect(self.replaceCall) toolBar.addAction(replaceAction) # create find action findAction = QAction(QIcon.fromTheme('edit-find'), 'Find', self) findAction.triggered.connect(self.findCall) toolBar.addAction(findAction) # create next action nextAction = QAction(QIcon.fromTheme('go-previous'), 'Find Previous', self) nextAction.triggered.connect(self.nextCall) toolBar.addAction(nextAction) toolBar.addSeparator() # create case action caseAction = QAction(QIcon.fromTheme('edit-case'), 'Aa', self) caseAction.setCheckable(1) caseAction.triggered.connect(self.caseCall) toolBar.addAction(caseAction) box = QHBoxLayout() box.addWidget(toolBar) box.addWidget(self.searchText) box.addWidget(self.replaceText) box.addStretch(1) self.bottomMenu.setLayout(box) return self.bottomMenu # callback functions built for easy class patching ########## # want to refrain from renaming these functions as it will break # any class patch user's use # we split them like this so a user can intercept the callback # but still call the original functionality def caseCall(self): self.case() def case(self): self.isCaseSensitive -=1 self.isCaseSensitive *=-1 print self.isCaseSensitive def exitCall(self): self.exit() def exit(self): if self.editor.isModified(): result = self.killCheck() if result: self.readOnlyMode() def findCall(self): self.find() def find(self): self.editor.search(str(self.searchText.text()), re=False, case=self.isCaseSensitive, word=False, wrap= False, fwd=True) def gcodeLexerCall(self): self.gcodeLexer() def gcodeLexer(self): self.editor.set_gcode_lexer() def nextCall(self): self.next() def next(self): self.editor.search(str(self.searchText.text()),False) self.editor.search_Next() def newCall(self): self.new() def new(self): if self.editor.isModified(): result = self.killCheck() if result: self.editor.new_text() def openCall(self): self.open() def open(self): self.getFileName() def openReturn(self,f): ACTION.OPEN_PROGRAM(f) self.editor.setModified(False) def pythonLexerCall(self): self.pythonLexer() def pythonLexer(self): self.editor.set_python_lexer() def redoCall(self): self.redo() def redo(self): self.editor.redo() def replaceCall(self): self.replace() def replace(self): self.editor.replace_text(str(self.replaceText.text())) def saveCall(self): self.save() def save(self): self.getSaveFileName() def saveReturn(self, fname): ACTION.SAVE_PROGRAM(self.editor.text(), fname) self.editor.setModified(False) ACTION.OPEN_PROGRAM(fname) def undoCall(self): self.undo() def undo(self): self.editor.undo() # helper functions ############################################ def _hal_init(self): # name the top and bottom frames so it's easier to style self.bottomMenu.setObjectName('%sBottomButtonFrame'% self.objectName()) self.topMenu.setObjectName('%sTopButtonFrame'% self.objectName()) def editMode(self): self.topMenu.show() self.bottomMenu.show() self.editor.setReadOnly(False) def readOnlyMode(self): self.topMenu.hide() self.bottomMenu.hide() self.editor.setReadOnly(True) def getFileName(self): mess = {'NAME':self.load_dialog_code,'ID':'%s__' % self.objectName(), 'TITLE':'Load Editor'} STATUS.emit('dialog-request', mess) def getSaveFileName(self): mess = {'NAME':self.save_dialog_code,'ID':'%s__' % self.objectName(), 'TITLE':'Save Editor'} STATUS.emit('dialog-request', mess) # process the STATUS return message def returnFromDialog(self, w, message): if message.get('NAME') == self.load_dialog_code: path = message.get('RETURN') code = bool(message.get('ID') == '%s__'% self.objectName()) if path and code: self.openReturn(path) elif message.get('NAME') == self.save_dialog_code: path = message.get('RETURN') code = bool(message.get('ID') == '%s__'% self.objectName()) if path and code: self.saveReturn(path) def killCheck(self): choice = QMessageBox.question(self, 'Warning!!', "This file has changed since loading...Still want to proceed?", QMessageBox.Yes | QMessageBox.No) if choice == QMessageBox.Yes: return True else: return False def emit_percent(self, percent): self.percentDone.emit(percent) # designer recognized getter/setters # auto_show_mdi status # These adjust the self.editor instance def set_auto_show_mdi(self, data): self.editor.auto_show_mdi = data def get_auto_show_mdi(self): return self.editor.auto_show_mdi def reset_auto_show_mdi(self): self.editor.auto_show_mdi = True auto_show_mdi_status = pyqtProperty(bool, get_auto_show_mdi, set_auto_show_mdi, reset_auto_show_mdi)
class VideoFinderAddLink(AddLinkWindow): formats_showing = [] media_title = '' running_thread = None threadPool = {} def __init__(self, parent, receiver_slot, settings, video_dict={}): super().__init__(parent, receiver_slot, settings, video_dict) self.setWindowTitle(QCoreApplication.translate("ytaddlink_src_ui_tr", 'Video Finder')) self.size_label.hide() # add support for other languages locale = str(self.persepolis_setting.value('settings/locale')) QLocale.setDefault(QLocale(locale)) self.translator = QTranslator() if self.translator.load(':/translations/locales/ui_' + locale, 'ts'): QCoreApplication.installTranslator(self.translator) # Fetch Button self.url_submit_button = QPushButton(self.link_frame) self.link_horizontalLayout.addWidget(self.url_submit_button) # Status Box self.status_box = QTextEdit(self.link_frame) self.status_box.setMaximumHeight(150) self.link_verticalLayout.addWidget(self.status_box) # Select format horizontal layout select_format_hl = QHBoxLayout() # Selection Label select_format_label = QLabel(self.link_frame) select_format_hl.addWidget(select_format_label) # Selection combobox self.media_combo = QComboBox(self.link_frame) self.media_combo.setMinimumWidth(200) select_format_hl.addWidget(self.media_combo) # Duration label self.duration_label = QLabel(self.link_frame) select_format_hl.addWidget(self.duration_label) self.selection_line = QFrame(self) self.selection_line.setLayout(select_format_hl) self.link_verticalLayout.addWidget(self.selection_line) # Set Texts self.url_submit_button.setText(QCoreApplication.translate("ytaddlink_src_ui_tr", 'Fetch Media List')) self.ok_pushButton.setText(QCoreApplication.translate("ytaddlink_src_ui_tr", 'Download Now')) select_format_label.setText(QCoreApplication.translate("ytaddlink_src_ui_tr", 'Select a format')) # Add Slot Connections self.url_submit_button.setEnabled(False) self.change_name_lineEdit.setEnabled(False) self.ok_pushButton.setEnabled(False) self.download_later_pushButton.setEnabled(False) self.url_submit_button.clicked.connect(self.submit_clicked) self.media_combo.currentIndexChanged.connect(self.media_selection_changed) self.link_lineEdit.textChanged.disconnect(super().linkLineChanged) # Should be disconnected. self.link_lineEdit.textChanged.connect(self.linkLineChangedHere) self.setMinimumSize(500, 400) self.status_box.hide() self.selection_line.hide() if 'link' in video_dict.keys() and video_dict['link']: self.link_lineEdit.setText(video_dict['link']) self.url_submit_button.setEnabled(True) else: # check clipboard clipboard = QApplication.clipboard() text = clipboard.text() if (("tp:/" in text[2:6]) or ("tps:/" in text[2:7])): self.link_lineEdit.setText(str(text)) self.url_submit_button.setEnabled(True) # Define native slots def url_changed(self, value): if ' ' in value or value == '': self.url_submit_button.setEnabled(False) self.url_submit_button.setToolTip(QCoreApplication.translate("ytaddlink_src_ui_tr", 'Please enter a valid video link')) else: self.url_submit_button.setEnabled(True) self.url_submit_button.setToolTip('') def submit_clicked(self, button=None): # Clear media list self.media_combo.clear() self.selection_line.hide() self.change_name_lineEdit.clear() self.threadPool.clear() self.change_name_checkBox.setChecked(False) self.formats_showing.clear() self.url_submit_button.setEnabled(False) self.status_box.setText(QCoreApplication.translate("ytaddlink_src_ui_tr", 'Fetching Media Info...')) self.status_box.show() self.ok_pushButton.setEnabled(False) self.download_later_pushButton.setEnabled(False) dictionary_to_send = deepcopy(self.plugin_add_link_dictionary) # More options more_options = self.collect_more_options() for k in more_options.keys(): dictionary_to_send[k] = more_options[k] dictionary_to_send['link'] = self.link_lineEdit.text() fetcher_thread = MediaListFetcherThread(self.fetched_result, dictionary_to_send, self) self.running_thread = fetcher_thread fetcher_thread.start() def filename_changed(self, value): if value.strip() == '': self.ok_pushButton.setEnabled(False) def media_selection_changed(self): try: self.change_name_lineEdit.setText(self.media_title + '.' + self.formats_showing[self.media_combo.currentIndex()]['ext']) self.change_name_checkBox.setChecked(True) except Exception as ex: logger.sendToLog(ex, "ERROR") def okButtonPressed(self, button, download_later): index = self.media_combo.currentIndex() self.link_lineEdit.setText(self.formats_showing[index]['url']) super().okButtonPressed(button, download_later) def fetched_result(self, media_dict): self.url_submit_button.setEnabled(True) if 'error' in media_dict.keys(): self.status_box.setText('<font color="#f11">' + str(media_dict['error']) + '</font>') self.status_box.show() else: # Show the media list self.media_title = media_dict['title'] i = 0 if 'formats' not in media_dict.keys() and 'entries' in media_dict.keys(): formats = media_dict['entries'] formats = formats[0] media_dict['formats'] = formats['formats'] elif 'formats' not in media_dict.keys() and 'format' in media_dict.keys(): media_dict['formats'] = [media_dict.copy()] try: for f in media_dict['formats']: text = '' if 'acodec' in f.keys(): if f['acodec'] == 'none' and f['vcodec'] != 'none' and self.persepolis_setting.value('settings/video_finder/hide_no_audio', 'yes') == 'yes': continue if f['acodec'] == 'none': text = 'No Audio {}p'.format(f['height']) if 'vcodec' in f.keys(): if f['vcodec'] == 'none' and f['acodec'] != 'none' and self.persepolis_setting.value('settings/video_finder/hide_no_video', 'yes') == 'yes': continue if f['vcodec'] == 'none': # No video, show audio bit rate text = 'Only Audio {}kbps'.format(f['abr']) if 'height' in f.keys(): text = '{}p'.format(f['height']) if 'ext' in f.keys(): text = '{} .{}'.format(text, f['ext']) if 'filesize' in f.keys() and f['filesize']: # Youtube api does not supply file size for some formats, so check it. text = '{} - {}'.format(text, get_readable_size(f['filesize'])) else: # Start spider to find file size input_dict = deepcopy(self.plugin_add_link_dictionary) # input_dict['out'] = self.media_title + str(f['ext']) input_dict['link'] = f['url'] more_options = self.collect_more_options() for key in more_options.keys(): input_dict[key] = more_options[key] size_fetcher = FileSizeFetcherThread(input_dict, i, self.file_size_found) self.threadPool[str(i)] = {'thread': size_fetcher, 'item_id': i} size_fetcher.start() # Add current format to combobox self.formats_showing.append(f) self.media_combo.addItem(text) i = i + 1 except Exception as ex: logger.sendToLog(ex, "ERROR") self.status_box.hide() if 'duration' in media_dict.keys(): self.duration_label.setText('Duration ' + get_readable_duration(media_dict['duration'])) self.selection_line.show() self.ok_pushButton.setEnabled(True) self.download_later_pushButton.setEnabled(True) def file_size_found(self, result): try: item_id = self.threadPool[str(result['thread_key'])]['item_id'] if result['file_size'] and result['file_size'] != '0': text = self.media_combo.itemText(item_id) self.media_combo.setItemText(item_id, '{} - {}'.format(text, result['file_size'])) else: # Retry sleep(0.8) self.threadPool[str(result['thread_key'])]['thread'].start() except Exception as ex: logger.sendToLog(ex, "ERROR") def linkLineChangedHere(self, lineEdit): if str(lineEdit) == '': self.url_submit_button.setEnabled(False) else: self.url_submit_button.setEnabled(True) # This method collects additional information like proxy ip, user, password etc. def collect_more_options(self): options = {'ip': None, 'port': None, 'proxy_user': None, 'proxy_passwd': None, 'download_user': None, 'download_passwd': None} if self.proxy_checkBox.isChecked(): options['ip'] = self.ip_lineEdit.text() options['port'] = self.port_spinBox.value() options['proxy_user'] = self.proxy_user_lineEdit.text() options['proxy_passwd'] = self.proxy_pass_lineEdit.text() if self.download_checkBox.isChecked(): options['download_user'] = self.download_user_lineEdit.text() options['download_passwd'] = self.download_pass_lineEdit.text() # These info (keys) are required for spider to find file size, because spider() does not check if key exists. additional_info = ['header', 'load_cookies', 'user_agent', 'referer', 'out'] for i in additional_info: if i not in self.plugin_add_link_dictionary.keys(): options[i] = None return options
class FindInFilesWidget(QWidget): def __init__(self, parent=None): super().__init__(parent) _ToolsDock.register_widget(translations.TR_FIND_IN_FILES, self) def install_widget(self): container = QHBoxLayout(self) container.setContentsMargins(3, 0, 3, 0) self._actions = FindInFilesActions(self) container.addWidget(self._actions) self.__count = 0 top_widget = QFrame() top_layout = QVBoxLayout(top_widget) top_layout.setContentsMargins(0, 0, 0, 0) top_layout.setSpacing(0) self._message_frame = QFrame() self._message_frame.hide() self._message_frame.setAutoFillBackground(True) pal = QPalette() pal.setColor(QPalette.Window, QColor("#6a6ea9")) pal.setColor(QPalette.WindowText, pal.windowText().color()) self._message_frame.setPalette(pal) self._message_label = QLabel("") message_layout = QHBoxLayout(self._message_frame) message_layout.addStretch(1) message_layout.setContentsMargins(2, 2, 2, 2) message_layout.addWidget(self._message_label) top_layout.addWidget(self._message_frame) self._tree_results = SearchResultTreeView(self) top_layout.addWidget(self._tree_results) container.addWidget(top_widget) self._main_container = IDE.get_service("main_container") # Search worker self._search_worker = FindInFilesWorker() search_thread = QThread() self._search_worker.moveToThread(search_thread) self._search_worker.resultAvailable.connect(self._on_worker_finished) search_thread.finished.connect(search_thread.deleteLater) self._actions.searchRequested.connect(self._on_search_requested) self._tree_results.activated.connect(self._go_to) def _clear_results(self): self.__count = 0 self._tree_results.clear() def _go_to(self, index): result_item = self._tree_results.model().data(index, Qt.UserRole + 1) if result_item.lineno != -1: parent = result_item.parent file_name = parent.file_path lineno = result_item.lineno # Open the file and jump to line self._main_container.open_file(file_name, line=lineno) @pyqtSlot('PyQt_PyObject') def _on_worker_finished(self, lines): self.__count += len(lines[-1]) self._message_frame.show() self._message_label.setText( translations.TR_MATCHES_FOUND.format(self.__count)) self._tree_results.add_result(lines) @pyqtSlot('QString', bool, bool, bool) def _on_search_requested(self, to_find, cs, regex, wo): self._clear_results() type_ = QRegExp.FixedString if regex: type_ = QRegExp.RegExp if wo: type_ = QRegExp.RegExp to_find = "|".join(["\\b" + word.strip() + "\\b" for word in to_find.split()]) filters = re.split(",", "*.py") pattern = QRegExp(to_find, cs, type_) self._search_worker.find_in_files( self._actions.current_project_path, filters, pattern, recursive=True ) def showEvent(self, event): self._actions._line_search.setFocus() super().showEvent(event)
class DolphinUpdate(QMainWindow): APP_TITLE = 'DolphinUpdate 3.0' DOWNLOAD_PATH = os.path.join(os.getenv('APPDATA'), 'DolphinUpdate/') def __init__(self, user_data_control): super().__init__() sys.excepthook = self._displayError self._udc = user_data_control self.check = QPixmap("res/check.png") self.cancel = QPixmap("res/cancel.png") self.setGeometry(500, 500, 500, 465) self.init_ui() self.init_window() self.init_user_data() self.setWindowTitle(self.APP_TITLE) self.setWindowIcon(QIcon('res/rabbit.png')) center(self) self.show() # PyQt Error Handling def _displayError(self, etype, evalue, etraceback): tb = ''.join(traceback.format_exception(etype, evalue, etraceback)) QMessageBox.critical( self, "FATAL ERROR", "An unexpected error occurred:\n%s\n\n%s" % (evalue, tb)) def init_ui(self): """create the UI elements in the main window""" self.statusBar().showMessage('Ready') main = QWidget() self.setCentralWidget(main) self.dolphin_dir = QLineEdit(main) self.dolphin_dir.setPlaceholderText( "Please Select a Dolphin Directory") self.dolphin_dir.setReadOnly(True) self.version = QLineEdit(main) self.version.setPlaceholderText("Installation Status Unknown") self.version.setReadOnly(True) self.current = QLineEdit(main) self.current.setPlaceholderText("Loading Current Version...") self.current.setReadOnly(True) self.changelog_frame = QFrame(main) changelog_vbox = QVBoxLayout(self.changelog_frame) self.changelog = QTextBrowser(main) self.changelog.setPlaceholderText("Loading Changelog...") self.changelog.setReadOnly(True) changelog_vbox.addWidget(QLabel('Changelog:')) changelog_vbox.addWidget(self.changelog) self.changelog_frame.setContentsMargins(0, 20, -7, 0) grid = QGridLayout() main.setLayout(grid) self.dolphin_dir_status = QLabel(main) self.dolphin_dir_status.setPixmap(self.cancel) self.version_status = QLabel(main) self.version_status.setPixmap(self.cancel) self.current_status = QLabel(main) self.current_status.setPixmap(QPixmap("res/info.png")) grid.addWidget(self.dolphin_dir_status, 0, 0, Qt.AlignCenter) grid.addWidget(QLabel('Dolphin Directory:'), 0, 2) grid.addWidget(self.dolphin_dir, 0, 3) grid.addWidget(self.version_status, 1, 0, Qt.AlignCenter) grid.addWidget(QLabel('Your Version:'), 1, 2) grid.addWidget(self.version, 1, 3) grid.addWidget(self.current_status, 2, 0, Qt.AlignCenter) grid.addWidget(QLabel('Current Version:'), 2, 2) grid.addWidget(self.current, 2, 3) grid.addWidget(self.changelog_frame, 3, 0, 1, 4) grid.setSpacing(10) grid.setVerticalSpacing(2) grid.setRowStretch(3, 1) def init_window(self): self.update_thread = UpdateThread() self.update_thread.current.connect(self.update_current) self.update_thread.changelog.connect(self.update_changelog) self.update_thread.error.connect(self.show_warning) self.update_thread.start() self.download_thread = DownloadThread() self.download_thread.status.connect(self.update_version) self.download_thread.error.connect(self.show_warning) open_action = QAction(QIcon('res/open.png'), '&Open', self) open_action.setShortcut('Ctrl+O') open_action.setStatusTip('Select Dolphin Folder') open_action.triggered.connect(self.select_dolphin_folder) self.hide_changelog_action = QAction('Hide Changelog', self) self.hide_changelog_action.setStatusTip('Hide Changelog Section') self.hide_changelog_action.setCheckable(True) self.hide_changelog_action.toggled.connect(self.hide_changelog) self.hide_changelog_action.setChecked(self._udc.get_hide_changelog()) update_action = QAction(QIcon('res/synchronize.png'), '&Refresh', self) update_action.setStatusTip('Refresh Current Version') update_action.triggered.connect(self.retrieve_current) download_action = QAction(QIcon('res/download.png'), '&Download', self) download_action.setStatusTip('Download Newest Version') download_action.triggered.connect(self.download_new) clear_action = QAction(QIcon('res/delete.png'), '&Clear Version', self) clear_action.setStatusTip('Reset Your Version') clear_action.triggered.connect(self.clear_version) exit_action = QAction(QIcon('res/exit.png'), '&Exit', self) exit_action.setShortcut('Ctrl+Q') exit_action.setStatusTip('Exit application') exit_action.triggered.connect(self.close) launch_dolphin_action = QAction(QIcon('res/dolphin.png'), '&Launch Dolphin', self) launch_dolphin_action.setShortcut('Ctrl+D') launch_dolphin_action.setStatusTip('Launch Dolphin') launch_dolphin_action.triggered.connect(self.launch_dolphin) file_menu = self.menuBar().addMenu('&File') file_menu.addAction(open_action) file_menu.addAction(update_action) file_menu.addAction(clear_action) file_menu.addAction(launch_dolphin_action) file_menu.addAction(exit_action) file_menu = self.menuBar().addMenu('&View') file_menu.addAction(self.hide_changelog_action) toolbar = self.addToolBar('Toolbar') toolbar.addAction(open_action) toolbar.addAction(update_action) toolbar.addAction(download_action) toolbar.addSeparator() toolbar.addAction(launch_dolphin_action) auto_launch_frame = QFrame() auto_launch_form = QFormLayout(auto_launch_frame) self.auto_launch_check = QCheckBox(auto_launch_frame) self.auto_launch_check.setChecked(self._udc.get_auto_launch()) auto_launch_form.addRow("Auto Launch?", self.auto_launch_check) auto_launch_form.setContentsMargins(0, 1, 2, 0) self.statusBar().addPermanentWidget(auto_launch_frame) def launch_dolphin(self): dolphin_dir = self.dolphin_dir.text() if not dolphin_dir: self.show_warning('Please select a dolphin folder.') return dolphin_path = os.path.join(dolphin_dir, 'Dolphin.exe') if not os.path.isfile(dolphin_path): self.show_warning('Could not find "Dolphin.exe".') return subprocess.Popen(dolphin_path, cwd=dolphin_dir) self.close() def update_version(self, message): if message == 'finished': self.version.setText(self.version.placeholderText()) self.version.setPlaceholderText("Installation Status Unknown") self.version_status.setPixmap(self.check) self._udc.set_user_version(self.version.text()) if self.auto_launch_check.isChecked(): self.launch_dolphin() else: self.version.setPlaceholderText(message) def download_new(self): dolphin_dir = self.dolphin_dir.text() version = self.version.text() if self.current.text() == version: self.show_warning('You already have the most recent version.') return elif not os.path.isdir(dolphin_dir): self.show_warning('Your dolphin folder path is invalid.') self.dolphin_dir_status.setPixmap(QPixmap("res/cancel.png")) return if not self.download_thread.isRunning(): if dir == 'Please Select a Dolphin Directory': self.show_warning('Please select a dolphin folder.') self.version.setText('') self.download_thread.update(dolphin_dir, version) self.download_thread.start() def update_changelog(self, message): self.changelog.setText(message) def show_warning(self, message): QMessageBox.warning(self, 'Uh-oh', message, QMessageBox.Ok) def clear_version(self): reply = QMessageBox.question( self, 'Clear', "Are you sure you want to reset your version?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.version.setText('') self.version_status.setPixmap(self.cancel) self._udc.set_user_version('') def retrieve_current(self): if ~self.update_thread.isRunning(): self.current.setText('') self.update_thread.start() def update_current(self, current): self.current.setText(current) if self.version.text() == self.current.text(): self.version_status.setPixmap(self.check) if self.auto_launch_check.isChecked(): self.launch_dolphin() else: self.version_status.setPixmap(self.cancel) if self.auto_launch_check.isChecked() and self.dolphin_dir.text(): self.download_new() def select_dolphin_folder(self): folder = str( QFileDialog.getExistingDirectory(self, 'Select Dolphin Directory')) if folder: self.dolphin_dir.setText(folder) self.dolphin_dir_status.setPixmap(QPixmap("res/check.png")) self._udc.set_user_path(folder) def hide_changelog(self, checked): self._udc.set_hide_changelog(checked) if checked: self.setMinimumHeight(250) self.changelog_frame.hide() self.resize(500, 250) else: self.setMinimumHeight(375) self.resize(500, 465) self.changelog_frame.show() def init_user_data(self): """initialize the dolphin path""" path, version = self._udc.load_user_data() if path: self.dolphin_dir.setText(path) if os.path.isdir(path): self.dolphin_dir_status.setPixmap(self.check) if version: self.version.setText(version) # PyQt closeEvent called on exit def closeEvent(self, event): self._udc.set_auto_launch(self.auto_launch_check.isChecked()) if self.download_thread.isRunning(): event.ignore() reply = QMessageBox.question(self, 'Exit', "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.hide() self.download_thread.finished.connect(qApp.quit) else: event.accept()
class VideoFinderAddLink(AddLinkWindow): formats_showing = [] media_title = '' running_thread = None threadPool = {} def __init__(self, parent, receiver_slot, settings, video_dict={}): super().__init__(parent, receiver_slot, settings, video_dict) self.setWindowTitle(QCoreApplication.translate("ytaddlink_src_ui_tr", 'Video Finder')) self.size_label.hide() # add support for other languages locale = str(self.persepolis_setting.value('settings/locale')) QLocale.setDefault(QLocale(locale)) self.translator = QTranslator() if self.translator.load(':/translations/locales/ui_' + locale, 'ts'): QCoreApplication.installTranslator(self.translator) # Fetch Button self.url_submit_button = QPushButton(self.link_frame) self.link_horizontalLayout.addWidget(self.url_submit_button) # Status Box self.status_box = QTextEdit(self.link_frame) self.status_box.setMaximumHeight(150) self.link_verticalLayout.addWidget(self.status_box) # Select format horizontal layout select_format_hl = QHBoxLayout() # Selection Label select_format_label = QLabel(self.link_frame) select_format_hl.addWidget(select_format_label) # Selection combobox self.media_combo = QComboBox(self.link_frame) self.media_combo.setMinimumWidth(200) select_format_hl.addWidget(self.media_combo) # Duration label self.duration_label = QLabel(self.link_frame) select_format_hl.addWidget(self.duration_label) self.selection_line = QFrame(self) self.selection_line.setLayout(select_format_hl) self.link_verticalLayout.addWidget(self.selection_line) # Set Texts self.url_submit_button.setText(QCoreApplication.translate("ytaddlink_src_ui_tr", 'Fetch Media List')) self.ok_pushButton.setText(QCoreApplication.translate("ytaddlink_src_ui_tr", 'Download Now')) select_format_label.setText(QCoreApplication.translate("ytaddlink_src_ui_tr", 'Select a format')) # Add Slot Connections self.url_submit_button.setEnabled(False) self.change_name_lineEdit.setEnabled(False) self.ok_pushButton.setEnabled(False) self.download_later_pushButton.setEnabled(False) self.url_submit_button.clicked.connect(self.submit_clicked) self.media_combo.currentIndexChanged.connect(self.media_selection_changed) self.link_lineEdit.textChanged.disconnect(super().linkLineChanged) # Should be disconnected. self.link_lineEdit.textChanged.connect(self.linkLineChangedHere) self.setMinimumSize(500, 400) self.status_box.hide() self.selection_line.hide() if 'link' in video_dict.keys() and video_dict['link']: self.link_lineEdit.setText(video_dict['link']) self.url_submit_button.setEnabled(True) else: # check clipboard clipboard = QApplication.clipboard() text = clipboard.text() if (("tp:/" in text[2:6]) or ("tps:/" in text[2:7])): self.link_lineEdit.setText(str(text)) self.url_submit_button.setEnabled(True) # Define native slots def url_changed(self, value): if ' ' in value or value == '': self.url_submit_button.setEnabled(False) self.url_submit_button.setToolTip(QCoreApplication.translate("ytaddlink_src_ui_tr", 'Please enter a valid video link')) else: self.url_submit_button.setEnabled(True) self.url_submit_button.setToolTip('') def submit_clicked(self, button=None): # Clear media list self.media_combo.clear() self.selection_line.hide() self.change_name_lineEdit.clear() self.threadPool.clear() self.change_name_checkBox.setChecked(False) self.formats_showing.clear() self.url_submit_button.setEnabled(False) self.status_box.setText(QCoreApplication.translate("ytaddlink_src_ui_tr", 'Fetching Media Info...')) self.status_box.show() self.ok_pushButton.setEnabled(False) self.download_later_pushButton.setEnabled(False) dictionary_to_send = deepcopy(self.plugin_add_link_dictionary) # More options more_options = self.collect_more_options() for k in more_options.keys(): dictionary_to_send[k] = more_options[k] dictionary_to_send['link'] = self.link_lineEdit.text() fetcher_thread = MediaListFetcherThread(self.fetched_result, dictionary_to_send, self) self.running_thread = fetcher_thread fetcher_thread.start() def filename_changed(self, value): if value.strip() == '': self.ok_pushButton.setEnabled(False) def media_selection_changed(self): try: self.change_name_lineEdit.setText(self.media_title + '.' + self.formats_showing[self.media_combo.currentIndex()]['ext']) self.change_name_checkBox.setChecked(True) except Exception as ex: logger.sendToLog(ex, "ERROR") def okButtonPressed(self, button, download_later): index = self.media_combo.currentIndex() self.link_lineEdit.setText(self.formats_showing[index]['url']) super().okButtonPressed(button, download_later) def fetched_result(self, media_dict): self.url_submit_button.setEnabled(True) if 'error' in media_dict.keys(): self.status_box.setText('<font color="#f11">' + str(media_dict['error']) + '</font>') self.status_box.show() else: # Show the media list self.media_title = media_dict['title'] i = 0 if 'formats' not in media_dict.keys() and 'entries' in media_dict.keys(): formats = media_dict['entries'] formats = formats[0] media_dict['formats'] = formats['formats'] elif 'formats' not in media_dict.keys() and 'format' in media_dict.keys(): media_dict['formats'] = [media_dict.copy()] try: for f in media_dict['formats']: text = '' if 'acodec' in f.keys(): if f['acodec'] == 'none' and f['vcodec'] != 'none' and self.persepolis_setting.value('settings/video_finder/hide_no_audio', 'yes') == 'yes': continue if f['acodec'] == 'none': text = text + '- No Audio' if 'vcodec' in f.keys(): if f['vcodec'] == 'none' and f['acodec'] != 'none' and self.persepolis_setting.value('settings/video_finder/hide_no_video', 'yes') == 'yes': continue if f['vcodec'] == 'none': # No video, show audio bit rate text = text + '- Only Audio {}kbps'.format(f['abr']) if 'height' in f.keys(): text = text + ' ' + '{}p'.format(f['height']) if 'ext' in f.keys(): text = text + ' ' + '.{}'.format(f['ext']) if 'filesize' in f.keys() and f['filesize']: # Youtube api does not supply file size for some formats, so check it. text = text + ' ' + '{}'.format(get_readable_size(f['filesize'])) else: # Start spider to find file size input_dict = deepcopy(self.plugin_add_link_dictionary) # input_dict['out'] = self.media_title + str(f['ext']) input_dict['link'] = f['url'] more_options = self.collect_more_options() for key in more_options.keys(): input_dict[key] = more_options[key] size_fetcher = FileSizeFetcherThread(input_dict, i, self.file_size_found) self.threadPool[str(i)] = {'thread': size_fetcher, 'item_id': i} size_fetcher.start() # Add current format to combobox self.formats_showing.append(f) self.media_combo.addItem(text) i = i + 1 except Exception as ex: logger.sendToLog(ex, "ERROR") self.status_box.hide() if 'duration' in media_dict.keys(): self.duration_label.setText('Duration ' + get_readable_duration(media_dict['duration'])) self.selection_line.show() self.ok_pushButton.setEnabled(True) self.download_later_pushButton.setEnabled(True) def file_size_found(self, result): try: item_id = self.threadPool[str(result['thread_key'])]['item_id'] if result['file_size'] and result['file_size'] != '0': text = self.media_combo.itemText(item_id) self.media_combo.setItemText(item_id, '{} - {}'.format(text, result['file_size'])) else: # Retry sleep(0.8) self.threadPool[str(result['thread_key'])]['thread'].start() except Exception as ex: logger.sendToLog(ex, "ERROR") def linkLineChangedHere(self, lineEdit): if str(lineEdit) == '': self.url_submit_button.setEnabled(False) else: self.url_submit_button.setEnabled(True) # This method collects additional information like proxy ip, user, password etc. def collect_more_options(self): options = {'ip': None, 'port': None, 'proxy_user': None, 'proxy_passwd': None, 'download_user': None, 'download_passwd': None} if self.proxy_checkBox.isChecked(): options['ip'] = self.ip_lineEdit.text() options['port'] = self.port_spinBox.value() options['proxy_user'] = self.proxy_user_lineEdit.text() options['proxy_passwd'] = self.proxy_pass_lineEdit.text() if self.download_checkBox.isChecked(): options['download_user'] = self.download_user_lineEdit.text() options['download_passwd'] = self.download_pass_lineEdit.text() # These info (keys) are required for spider to find file size, because spider() does not check if key exists. additional_info = ['header', 'load_cookies', 'user_agent', 'referer', 'out'] for i in additional_info: if i not in self.plugin_add_link_dictionary.keys(): options[i] = None return options
def hide(self): QFrame.hide(self)
class RelativeLocator(QWidget): def __init__(self): super(QWidget, self).__init__() self.layout = QVBoxLayout(self) self.plot_regions = GraphWidgets.GraphView3D() self.plot_trajectory = GraphWidgets.GraphView3D() self.plot_trajectory_magnitude = GraphWidgets.GraphView2D() self.display_pass_times = QFrame() self.display_pass_times_layout = QVBoxLayout() self.display_pass_times_table = QTableWidget() self.display_pass_times_graph = GraphWidgets.GraphView2D() self.display_pass_times_layout.addWidget(self.display_pass_times_table) self.display_pass_times_layout.addWidget(self.display_pass_times_graph) self.display_pass_times_graph.hide() self.display_pass_times_switch_button = QPushButton("change display") self.display_pass_times_switch_button.clicked.connect( self.when_display_pass_times_switch_button_clicked) self.display_pass_times_layout.addWidget( self.display_pass_times_switch_button) self.display_pass_times.setLayout(self.display_pass_times_layout) # set column count self.display_pass_times_table.setColumnCount(2) self.display_pass_times_table.setVerticalHeaderLabels( ["Pass Number", "Pass Duration"]) self.display_pass_times_table.horizontalHeader().setSectionResizeMode( 0, QtWidgets.QHeaderView.Stretch) self.display_pass_times_table.horizontalHeader().setSectionResizeMode( 1, QtWidgets.QHeaderView.Stretch) self.layout.addWidget(self.plot_regions) self.layout.addWidget(self.plot_trajectory) self.layout.addWidget(self.display_pass_times) self.layout.addWidget(self.plot_trajectory_magnitude) self.plot_regions.hide() self.display_pass_times.hide() self.plot_trajectory_magnitude.hide() self.bottom_panel = QFrame() self.bottom_layout = QHBoxLayout() self.plot_regions_button = QPushButton("plot regions") self.plot_regions_button.clicked.connect( self.when_plot_regions_button_clicked) self.plot_trajectory_button = QPushButton("plot trajectory") self.plot_trajectory_button.clicked.connect( self.when_plot_trajectory_button_clicked) self.display_pass_times_button = QPushButton("show pass times") self.display_pass_times_button.clicked.connect( self.when_display_pass_times_button_clicked) self.display_magnitude_button = QPushButton("show distance magnitude") self.display_magnitude_button.clicked.connect( self.when_plot_magnitude_button_clicked) self.bottom_layout.addWidget(self.plot_regions_button) self.bottom_layout.addWidget(self.plot_trajectory_button) self.bottom_layout.addWidget(self.display_pass_times_button) self.bottom_layout.addWidget(self.display_magnitude_button) self.enter_trajectory = QLineEdit( "") # enter in format "0.0, 0.0, 0.0, 0.0, 0.0, 0.0" self.bottom_panel.setLayout(self.bottom_layout) self.layout.addWidget(self.bottom_panel) self.thresh_min = 0 self.thresh_max = 10 self.state = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] self.end_seconds = 20000 self.resolution = self.end_seconds self.times = np.linspace(0.0, self.end_seconds, int(self.resolution)) self.trajectory = [[], [], []] self.reference_orbit = None def when_display_pass_times_switch_button_clicked(self): if self.display_pass_times_graph.isVisible(): self.display_pass_times_graph.hide() self.display_pass_times_table.show() else: self.display_pass_times_table.hide() self.display_pass_times_graph.show() def when_plot_regions_button_clicked(self): self.display_pass_times.hide() self.plot_trajectory.hide() self.plot_trajectory_magnitude.hide() self.plot_regions.show() def when_plot_trajectory_button_clicked(self): self.plot_regions.hide() self.display_pass_times.hide() self.plot_trajectory_magnitude.hide() self.plot_trajectory.show() def when_display_pass_times_button_clicked(self): self.plot_regions.hide() self.plot_trajectory.hide() self.plot_trajectory_magnitude.hide() self.display_pass_times.show() def when_plot_magnitude_button_clicked(self): self.plot_regions.hide() self.plot_trajectory.hide() self.display_pass_times.hide() self.plot_trajectory_magnitude.show() def specify_trajectory(self, state, end_seconds, reference_orbit, thresh_min, thresh_max): self.reference_orbit = reference_orbit self.state = state self.thresh_min = thresh_min self.thresh_max = thresh_max self.end_seconds = end_seconds self.resolution = self.end_seconds self.times = np.linspace(0.0, self.end_seconds, int(self.resolution)) self.populate_region_graph() self.populate_trajectory_graph() self.populate_time_graph() self.populate_magnitude_graph() def populate_region_graph(self): t_in, data_in, t_out, data_out = J2RelativeMotion.j2_sedwick_propagator( self.state, self.reference_orbit, self.times, self.times[1] - self.times[0], 2, self.thresh_min, self.thresh_max, False) data = [data_in, data_out] self.plot_regions.update_scatter( data, "Relative Motion for " + str(self.end_seconds) + " seconds | Trajectory: " + str(self.state), ["Within Range", "Out of Range"], ["Radial (m)", "In-Track (m)", "Cross-Track (m)"]) def populate_trajectory_graph(self): print(self.state) trajectory = J2RelativeMotion.j2_sedwick_propagator( self.state, self.reference_orbit, self.times, self.times[1] - self.times[0], 0, self.thresh_min, self.thresh_max, False) self.plot_trajectory.update_graph( [ trajectory, ], "Relative Motion for " + str(self.end_seconds) + " seconds | Trajectory: " + str(self.state), ["Radial (m)", "In-Track (m)", "Cross-Track (m)"]) def populate_time_graph(self): times = J2RelativeMotion.j2_sedwick_propagator( self.state, self.reference_orbit, self.times, self.times[1] - self.times[0], 3, self.thresh_min, self.thresh_max, False) # set row count self.display_pass_times_table.setRowCount(len(times)) for i in range(len(times)): self.display_pass_times_table.setItem( i, 1, QTableWidgetItem(str(times[i]))) self.display_pass_times_table.setItem(i, 0, QTableWidgetItem(str(i))) self.display_pass_times_graph.update_graph( [ times, ], "Opportunities for " + str(self.end_seconds)[:8] + " seconds | Trajectory: " + str(self.state[0])[:7] + ", " + str(self.state[1])[:7] + ", " + str(self.state[2])[:7] + ", " + str(self.state[3])[:7] + ", " + str(self.state[4])[:7] + ", " + str(self.state[5])[:7] + ", ", ["Pass Number", "Amount of Time (s)"]) def populate_magnitude_graph(self): magnitudes = J2RelativeMotion.j2_sedwick_propagator( self.state, self.reference_orbit, self.times, self.times[1] - self.times[0], 4, self.thresh_min, self.thresh_max, False) self.plot_trajectory_magnitude.update_graph( [ magnitudes, ], "Distance Magnitude for " + str(self.end_seconds)[:8] + " seconds | Trajectory: " + str(self.state[0])[:7] + ", " + str(self.state[1])[:7] + ", " + str(self.state[2])[:7] + ", " + str(self.state[3])[:7] + ", " + str(self.state[4])[:7] + ", " + str(self.state[5])[:7] + ", ", ["Time (s)", "Distance (m)"])
class TassomaiUI(object): def __init__(self, main_window: QMainWindow): self.win = main_window def setupUi(self): self.win.setWindowTitle(f"Tassomai Automation v{__version__}") self.win.setWindowIcon(QIcon(path('images', 'logo.png'))) self.win.resize(665, 580) self.centralwidget = QWidget(self.win) self.formLayout = QFormLayout(self.centralwidget) self.formLayout.setContentsMargins(5, 0, 5, -1) self.topFrame = QFrame(self.centralwidget) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.topFrame.sizePolicy().hasHeightForWidth()) self.topFrame.setSizePolicy(sizePolicy) self.topFrame.setAutoFillBackground(True) self.topFrame.setFrameShape(QFrame.StyledPanel) self.topFrame.setFrameShadow(QFrame.Raised) self.gridLayout = QGridLayout(self.topFrame) self.tassomaiImage = QLabel(self.topFrame) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tassomaiImage.sizePolicy().hasHeightForWidth()) self.tassomaiImage.setSizePolicy(sizePolicy) self.tassomaiImage.setPixmap(QPixmap(path('images', 'banner.png'))) self.gridLayout.addWidget(self.tassomaiImage, 0, 0, 1, 1) self.formLayout.setWidget(0, QFormLayout.SpanningRole, self.topFrame) self.tab = QTabWidget(self.centralwidget) self.main_tab = QWidget() self.automation_tab = QWidget() self.gridLayout_4 = QGridLayout(self.main_tab) self.gridLayout_4.setContentsMargins(0, 0, 0, 0) self.main_frame = QFrame(self.main_tab) self.main_frame.setAutoFillBackground(True) self.main_frame.setFrameShape(QFrame.StyledPanel) self.main_frame.setFrameShadow(QFrame.Raised) self.gridLayout_2 = QGridLayout(self.main_frame) self.gridLayout_2.setContentsMargins(5, 6, 2, -1) self.gridLayout_2.setVerticalSpacing(10) self.gridLayout_5 = QGridLayout(self.automation_tab) self.gridLayout_5.setContentsMargins(0, 0, 0, 0) self.automation_frame = QFrame(self.automation_tab) self.automation_frame.setAutoFillBackground(True) self.automation_frame.setFrameShape(QFrame.StyledPanel) self.automation_frame.setFrameShadow(QFrame.Raised) self.delayLayout = QHBoxLayout() self.delayLayout.setContentsMargins(0, 0, 0, 0) self.delayLayout.setSpacing(3) self.delay = QCheckBox(self.main_frame) font = QFont() font.setPointSize(10) self.delay.setFont(font) self.delayLayout.addWidget(self.delay) self.amountOfDelay = QDoubleSpinBox(self.main_frame) self.amountOfDelay.setMinimumWidth(70) self.amountOfDelay.setMaximum(25.00) self.delayLayout.addWidget(self.amountOfDelay) self.label03 = QLabel(self.main_frame) self.label03.setSizePolicy(sizePolicy) self.label03.setFont(font) self.delayLayout.addWidget(self.label03) self.amountOfDelay2 = QDoubleSpinBox(self.main_frame) self.amountOfDelay2.setMinimumWidth(70) self.amountOfDelay2.setMaximum(25.00) self.delayLayout.addWidget(self.amountOfDelay2) self.label3 = QLabel(self.main_frame) self.label3.setSizePolicy(sizePolicy) self.label3.setFont(font) self.delayLayout.addWidget(self.label3) self.whenDelay = QComboBox(self.main_frame) self.whenDelay.addItem("question") self.whenDelay.addItem("quiz") self.whenDelay.setMaximumWidth(100) self.delayLayout.addWidget(self.whenDelay) self.verticalSpacer1 = QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Expanding) self.delayLayout.addItem(self.verticalSpacer1) self.gridLayout_2.addLayout(self.delayLayout, 2, 0, 1, 1) self.randomnessLayout = QHBoxLayout() self.randomnessLayout.setContentsMargins(0, 0, 0, 0) self.randomnessLayout.setSpacing(3) self.randomness = QCheckBox(self.main_frame) self.randomness.setFont(font) self.randomness.setMaximumWidth(338) self.randomnessLayout.addWidget(self.randomness) self.randomnessAmount = QSpinBox(self.main_frame) self.randomnessAmount.setMinimumWidth(70) self.randomnessAmount.setMaximum(600) self.randomnessLayout.addWidget(self.randomnessAmount) self.label4 = QLabel(self.main_frame) self.label4.setSizePolicy(sizePolicy) self.label4.setFont(font) self.randomnessLayout.addWidget(self.label4) self.gridLayout_2.addLayout(self.randomnessLayout, 3, 0, 1, 1) self.dailyGoal = QCheckBox(self.main_frame) font = QFont() font.setPointSize(10) self.dailyGoal.setFont(font) self.gridLayout_2.addWidget(self.dailyGoal, 4, 0, 1, 1) self.bonusGoal = QCheckBox(self.main_frame) self.bonusGoal.setFont(font) self.gridLayout_2.addWidget(self.bonusGoal, 5, 0, 1, 1) self.horizontalLayout = QHBoxLayout() self.label1 = QLabel(self.main_frame) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.label1.sizePolicy().hasHeightForWidth()) self.label1.setSizePolicy(sizePolicy) font = QFont() font.setPointSize(10) self.label1.setFont(font) self.horizontalLayout.addWidget(self.label1) self.maxQuizes = QSpinBox(self.main_frame) self.maxQuizes.setMinimum(1) self.maxQuizes.setMaximum(1000000) self.maxQuizes.setProperty("value", 1000) self.horizontalLayout.addWidget(self.maxQuizes) self.label2 = QLabel(self.main_frame) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.label2.sizePolicy().hasHeightForWidth()) self.label2.setSizePolicy(sizePolicy) font = QFont() font.setPointSize(10) self.label2.setFont(font) self.horizontalLayout.addWidget(self.label2) self.gridLayout_2.addLayout(self.horizontalLayout, 1, 0, 1, 1) self.userBox = QGroupBox(self.main_frame) font = QFont() font.setPointSize(9) font.setBold(False) font.setWeight(50) self.userBox.setFont(font) self.gridLayout_3 = QGridLayout(self.userBox) self.emailTassomaiLabel = QLabel(self.userBox) self.gridLayout_3.addWidget(self.emailTassomaiLabel, 0, 0, 1, 1) self.emailTassomai = QLineEdit(self.userBox) self.gridLayout_3.addWidget(self.emailTassomai, 0, 1, 1, 1) self.passwordTassomaiLabel = QLabel(self.userBox) self.gridLayout_3.addWidget(self.passwordTassomaiLabel, 1, 0, 1, 1) self.passwordTassomai = QLineEdit(self.userBox) self.passwordTassomai.setEchoMode(QLineEdit.Password) self.gridLayout_3.addWidget(self.passwordTassomai, 1, 1, 1, 1) self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout_3.addItem(self.verticalSpacer, 2, 0, 1, 1) self.gridLayout_4.addWidget(self.main_frame, 0, 0, 1, 1) self.gridLayout_5.addWidget(self.automation_frame, 0, 0, 1, 1) self.tab.addTab(self.main_tab, "") self.tab.addTab(self.automation_tab, "") self.formLayout.setWidget(1, QFormLayout.SpanningRole, self.tab) self.gridLayout_2.addWidget(self.userBox, 0, 0, 1, 1) self.buttonsLayout = QHBoxLayout() self.bottom_frame = QFrame(self.centralwidget) self.bottom_frame.setFrameShape(QFrame.StyledPanel) self.bottom_frame.setFrameShadow(QFrame.Raised) self.gridLayout_7 = QGridLayout(self.bottom_frame) self.gridLayout_7.setContentsMargins(0, 0, 0, 0) self.startButton = QPushButton(self.bottom_frame) self.buttonsLayout.addWidget(self.startButton) self.stopButton = QPushButton(self.bottom_frame) self.buttonsLayout.addWidget(self.stopButton) self.gridLayout_7.addLayout(self.buttonsLayout, 0, 0, 1, 1) self.output = QTextEdit(self.bottom_frame) self.gridLayout_7.addWidget(self.output, 1, 0, 1, 1) self.formLayout.setWidget(2, QFormLayout.SpanningRole, self.bottom_frame) self.win.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(self.win) self.menubar.setGeometry(QRect(0, 0, 665, 21)) self.tools_menu = QMenu(self.menubar) self.uninstall_option = QAction() self.tools_menu.addAction(self.uninstall_option) self.menubar.addAction(self.tools_menu.menuAction()) self.win.setMenuBar(self.menubar) self.createTable() self.retranslateUi() self.tab.setCurrentIndex(0) self.tab.currentChanged['int'].connect(lambda k: self.bottom_frame.hide() if k != 0 else self.bottom_frame.show()) QMetaObject.connectSlotsByName(self.win) def retranslateUi(self): self.dailyGoal.setChecked(True) self.dailyGoal.setText("Finish when daily goal complete") self.bonusGoal.setText("Finish when bonus goal complete") self.delay.setText("Add a delay between") self.label03.setText("and") self.label3.setText("seconds between each") self.randomness.setText("Make it so that you answer a question incorrectly every") self.label4.setText("questions") self.label1.setText("Only do a maximum of ") self.label2.setText(" quiz(s)") self.userBox.setTitle("User Settings") self.passwordTassomaiLabel.setText("Password for Tassomai login") self.emailTassomaiLabel.setText("Email for Tassomai login") self.tab.setTabText(self.tab.indexOf(self.main_tab), "General") self.tab.setTabText(self.tab.indexOf(self.automation_tab), "Automation") self.startButton.setText("Start Automation") self.stopButton.setText("Stop Automation") self.tools_menu.setTitle("Tools") self.uninstall_option.setText("Uninstall (coming soon)") self.output.setReadOnly(True) self.startButton.setEnabled(True) self.stopButton.setEnabled(False) self.output.setHtml("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" "</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">-------------------------------------------</p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:8pt; font-weight:600; text-decoration: underline; color:#14860a;\">All output will go here<br /></span></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">-------------------------------------------</p>\n" ) def createTable(self): self.table = QTableWidget(self.automation_tab) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table.setAlternatingRowColors(True) self.table.setSelectionMode(QAbstractItemView.SingleSelection) self.table.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) self.table.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel) self.table.setShowGrid(True) self.table.setGridStyle(Qt.DashLine) self.table.setRowCount(999999) self.table.setColumnCount(6) for i in range(6): self.table.setHorizontalHeaderItem(i, QTableWidgetItem()) self.table.horizontalHeaderItem(i).setTextAlignment(Qt.AlignLeft) for i in range(6): self.table.setItem(0, i, QTableWidgetItem()) self.table.setItem(1, i, QTableWidgetItem()) self.table.horizontalHeader().setVisible(True) self.table.horizontalHeader().setHighlightSections(True) self.table.verticalHeader().setVisible(False) self.table.verticalHeader().setHighlightSections(True) self.gridLayout_5.addWidget(self.table, 0, 0, 1, 1) headers = ["Quiz", "Num", "Question", "Correct", "Time", "Answer"] for header in headers: item = self.table.horizontalHeaderItem(headers.index(header)) item.setText(header) item.setSizeHint(QSize(25, 25)) self.table.setColumnWidth(0, 40) self.table.setColumnWidth(1, 40) self.table.setColumnWidth(2, 175) self.table.setColumnWidth(3, 80) self.table.setColumnWidth(4, 80) self.table.setColumnWidth(5, 230)
class ParameterTab(QWidget): def __init__(self, options, favorites, settings, parent=None): super().__init__(parent=parent) # Building widget tab 2. # Button for selecting download location. self.browse_btn = QPushButton('Browse') self.save_profile_btn = QPushButton('Save Profile') self.save_profile_btn.resize(self.save_profile_btn.sizeHint()) self.download_label = QLabel('Download to:') self.favlabel = QLabel('Favorites:') self.optlabel = QLabel('All settings:') # LineEdit for download location. self.download_lineedit = QLineEdit() self.download_lineedit.setReadOnly(True) self.download_lineedit.setFocusPolicy(Qt.NoFocus) if settings.is_activate('Download location'): self.download_lineedit.setText('') self.download_lineedit.setToolTip(settings.get_active_setting('Download location')) else: self.download_lineedit.setText('DL') self.download_lineedit.setToolTip('Default download location.') self.download_lineedit.setContextMenuPolicy(Qt.ActionsContextMenu) # Sets up the parameter tree. self.options = ParameterTree(options, self) self.favorites = ParameterTree(favorites, self) self.favorites.favorite = True # Can only be toggled in settings manually if settings.user_options['show_collapse_arrows']: self.options.setRootIsDecorated(True) self.favorites.setRootIsDecorated(True) else: self.options.setRootIsDecorated(False) self.favorites.setRootIsDecorated(False) self.open_folder_action = QAction('Open location', parent=self.download_lineedit) self.copy_action = QAction('Copy', parent=self.download_lineedit) self.download_lineedit.addAction(self.open_folder_action) self.download_lineedit.addAction(self.copy_action) # Layout tab 2. self.QH = QHBoxLayout() # Adds widgets to the horizontal layout. label, lineedit and button. self.QH.addWidget(self.download_label) self.QH.addWidget(self.download_lineedit) self.QH.addWidget(self.browse_btn) self.QH.addWidget(self.save_profile_btn) self.QV = QVBoxLayout() self.QV.addLayout(self.QH, stretch=0) self.fav_frame = QFrame() self.opt_frame2 = QFrame() self.opt_frame2.setFrameShape(QFrame.HLine) self.fav_frame.setFrameShape(QFrame.HLine) self.fav_frame.setLineWidth(2) self.opt_frame2.setLineWidth(2) self.fav_frame.setObjectName('line') self.opt_frame2.setObjectName('line') self.fav_layout = QVBoxLayout() self.opt_layout = QVBoxLayout() self.fav_layout.setSizeConstraint(QVBoxLayout.SetMinimumSize) self.fav_layout.addWidget(self.favlabel, stretch=0) self.fav_layout.addWidget(self.fav_frame, stretch=0) self.fav_layout.addWidget(self.favorites, stretch=1, alignment=Qt.AlignTop) self.opt_layout.addWidget(self.optlabel, stretch=0) self.opt_layout.addWidget(self.opt_frame2, stretch=0) self.opt_layout.addWidget(self.options, stretch=1, alignment=Qt.AlignTop) self.parameter_layout = QHBoxLayout() self.parameter_layout.addLayout(self.fav_layout) self.parameter_layout.addLayout(self.opt_layout) self.QV.addLayout(self.parameter_layout) self.setLayout(self.QV) self.download_option = self.find_download_widget() def enable_favorites(self, enable): if not enable: self.favorites.hide() self.fav_frame.hide() self.favlabel.hide() else: self.favorites.show() self.fav_frame.show() self.favlabel.show() def find_download_widget(self): """ Finds the download widget. """ # TODO: Refactor to check the settings file/object, not the parameterTrees. for item in self.favorites.topLevelItems(): if item.data(0, DATA_SLOT) == 'Download location': self.download_option = item return item for item in self.options.topLevelItems(): if item.data(0, DATA_SLOT) == 'Download location': self.download_option = item return item raise SettingsError('No download item found in settings.')
class FindInFilesWidget(QWidget): def __init__(self, parent=None): super().__init__(parent) _ToolsDock.register_widget(translations.TR_FIND_IN_FILES, self) def install_widget(self): container = QHBoxLayout(self) container.setContentsMargins(3, 0, 3, 0) self._actions = FindInFilesActions(self) container.addWidget(self._actions) self.__count = 0 top_widget = QFrame() top_layout = QVBoxLayout(top_widget) top_layout.setContentsMargins(0, 0, 0, 0) top_layout.setSpacing(0) self._message_frame = QFrame() self._message_frame.hide() self._message_frame.setAutoFillBackground(True) pal = QPalette() pal.setColor(QPalette.Window, QColor("#6a6ea9")) pal.setColor(QPalette.WindowText, pal.windowText().color()) self._message_frame.setPalette(pal) self._message_label = QLabel("") message_layout = QHBoxLayout(self._message_frame) message_layout.addStretch(1) message_layout.setContentsMargins(2, 2, 2, 2) message_layout.addWidget(self._message_label) top_layout.addWidget(self._message_frame) self._tree_results = SearchResultTreeView(self) top_layout.addWidget(self._tree_results) container.addWidget(top_widget) self._main_container = IDE.get_service("main_container") # Search worker self._search_worker = FindInFilesWorker() search_thread = QThread() self._search_worker.moveToThread(search_thread) self._search_worker.resultAvailable.connect(self._on_worker_finished) search_thread.finished.connect(search_thread.deleteLater) self._actions.searchRequested.connect(self._on_search_requested) self._tree_results.activated.connect(self._go_to) def _clear_results(self): self.__count = 0 self._tree_results.clear() def _go_to(self, index): result_item = self._tree_results.model().data(index, Qt.UserRole + 1) if result_item.lineno != -1: parent = result_item.parent file_name = parent.file_path lineno = result_item.lineno # Open the file and jump to line self._main_container.open_file(file_name, line=lineno) @pyqtSlot('PyQt_PyObject') def _on_worker_finished(self, lines): self.__count += len(lines[-1]) self._message_frame.show() self._message_label.setText( translations.TR_MATCHES_FOUND.format(self.__count)) self._tree_results.add_result(lines) @pyqtSlot('QString', bool, bool, bool) def _on_search_requested(self, to_find, cs, regex, wo): self._clear_results() type_ = QRegExp.FixedString if regex: type_ = QRegExp.RegExp if wo: type_ = QRegExp.RegExp to_find = "|".join( ["\\b" + word.strip() + "\\b" for word in to_find.split()]) filters = re.split(",", "*.py") pattern = QRegExp(to_find, cs, type_) self._search_worker.find_in_files(self._actions.current_project_path, filters, pattern, recursive=True) def showEvent(self, event): self._actions._line_search.setFocus() super().showEvent(event)
class UI(QMainWindow): ''' GUI ''' def __init__(self, model_dir: str, model_language: str, model_status: str): super().__init__() self.setAcceptDrops(True) # create menu actions menubar = self.menuBar() windowMenu = menubar.addMenu('&Window') exitAction = QAction(' &Minimize', self) exitAction.setShortcut('Ctrl+M') exitAction.triggered.connect(self.minimize) windowMenu.addAction(exitAction) zoomInAction = QAction(' &Zoom in', self) zoomInAction.setShortcut(QKeySequence.ZoomIn) zoomInAction.triggered.connect(self.zoomIn) windowMenu.addAction(zoomInAction) zoomOutAction = QAction(' &Zoom out', self) zoomOutAction.setShortcut(QKeySequence.ZoomOut) zoomOutAction.triggered.connect(self.zoomOut) windowMenu.addAction(zoomOutAction) originalSizeAction = QAction(' &Original Size', self) originalSizeAction.setShortcut('Ctrl+0') originalSizeAction.triggered.connect(self.originalSize) windowMenu.addAction(originalSizeAction) central_layout = QVBoxLayout() # # label row header_layout = QHBoxLayout() text_label = QLabel('Source') text_label.setAlignment(Qt.AlignCenter) header_layout.addWidget(text_label) summarizer_label = QLabel('T5 Summarizer') summarizer_label.setAlignment(Qt.AlignCenter) header_layout.addWidget(summarizer_label) header_layout.setContentsMargins(0, 0, 0, 0) self.header_frame = QFrame() self.header_frame.setLayout(header_layout) central_layout.addWidget(self.header_frame) self.header_frame.hide() # summarization rows self.summarizationLayout = QGridLayout() self.input = QPlainTextEdit(placeholderText='Insert text to summarize') self.input.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.input.installEventFilter(self) # press Enter to summarize self.summarizationLayout.addWidget(self.input, 1, 0) # widget, position --> row index, column index setup_layout = QVBoxLayout() self.summarize_button = QPushButton('Summarize text box') self.summarize_button.clicked.connect(self.summarize_input_field) setup_layout.addStretch(1) setup_layout.addWidget(self.summarize_button) uploadFileButton = QPushButton('Upload text file') uploadFileButton.clicked.connect(self.upload_file_event) setup_layout.addWidget(uploadFileButton) slider_layout = QHBoxLayout() slider_layout.addWidget(QLabel('Summary length:')) self.sl = QSlider(Qt.Horizontal) self.sl.setMinimum(1) self.sl.setMaximum(3) self.sl.setValue(1) self.sl.setTickInterval(1) self.slider_len_settings = { 1: (0.05, 0.15), 2: (0.25, 0.4), 3: (0.5, 0.65) } self.lower_token_ratio = self.slider_len_settings[1][0] self.upper_token_ratio = self.slider_len_settings[1][1] self.sl.valueChanged.connect(self.slider_value_change) slider_layout.addWidget(self.sl) setup_layout.addLayout(slider_layout) setup_layout.addStretch(1) setup_layout.setContentsMargins(0, 0, 0, 0) self.setup_widget = QWidget() self.setup_widget.setLayout(setup_layout) self.summarizationLayout.addWidget(self.setup_widget, 1, 1) # widget, position --> row index, column index self.scroll = QScrollArea() self.scroll.setFrameStyle(QFrame.NoFrame) self.scroll.setWidgetResizable(True) self.central_frame = QFrame() self.central_frame.setLayout(self.summarizationLayout) self.summarizationLayout.setContentsMargins(0, 0, 0, 0) self.scroll.setWidget(self.central_frame) central_layout.addWidget(self.scroll) self.central_widget = QWidget() self.central_widget.setLayout(central_layout) self.setCentralWidget(self.central_widget) self.setWindowTitle(f"Text Summarizer: {model_dir} {model_language} {model_status}") if model_dir != 'dev': self.summarizer = AbstractiveSummarizer( model_dir, model_language, status=model_status ) self.next_summary_position = 1 def slider_value_change(self): setting_nr = self.sl.value() len_setting = self.slider_len_settings[setting_nr] self.lower_token_ratio = len_setting[0] self.upper_token_ratio = len_setting[1] def eventFilter(self, obj, event): ''' activates self.summarize when Enter is pressed ''' if event.type() == QEvent.KeyPress and obj is self.input: if event.key() == Qt.Key_Return and self.input.hasFocus(): self.summarize_input_field() return True return False def originalSize(self): ''' resets font size ''' self.central_widget.setFont(QFont(".AppleSystemUIFont", 13)) def minimize(self): ''' minimize window in operating system ''' self.setWindowState(self.windowState() | QWindow.Minimized) def summarize_input_field(self): text = self.read_input_field() if text: self.summarize_string(text, self.next_summary_position) self.next_summary_position += 1 self.append_new_row_to_layout() def read_input_field(self): textString = self.input.toPlainText() return textString.strip() def summarize_string(self, text: str, position_in_layout: int): ''' summarize the text in the input field ''' text_input_field = QTextEdit(text) text_input_field.setReadOnly(True) self.summarizationLayout.addWidget(text_input_field, position_in_layout, 0) summarize_label = QLabel('Summarizing...') summarize_label.setAlignment(Qt.AlignCenter) self.summarizationLayout.addWidget(summarize_label, position_in_layout, 1) modelRunner = ModelRunner(self.summarizer, text, position_in_layout, window=self) modelRunner.start() modelRunner.summary_output.connect(self.summarize_finished) self.input.setFocus() def summarize_finished(self, summary_output): self.header_frame.show() summary_text_field = QTextEdit(summary_output['summary']) summary_text_field.setReadOnly(True) position_in_layout = summary_output['position_in_layout'] self.summarizationLayout.addWidget(summary_text_field, position_in_layout, 1) self.summarizationLayout.setRowMinimumHeight(position_in_layout, 120) def append_new_row_to_layout(self): nrRows = self.next_summary_position + 1 self.summarizationLayout.addWidget(self.input, nrRows, 0) self.input.clear() self.summarizationLayout.addWidget(self.setup_widget, nrRows, 1) def upload_file_event(self): fileProps = QFileDialog.getOpenFileName(self, 'Open File') filename = fileProps[0] if filename: self.summarize_file(filename) def read_lines_from_file_path(self, file_path): with open(file_path, 'r') as f: texts = f.read() return texts.split('\n') def summarize_file(self, file_path): texts = self.read_lines_from_file_path(file_path) for i, text in enumerate(texts): self.summarize_string(text, self.next_summary_position + i) if i == 10: break self.next_summary_position += len(texts) self.append_new_row_to_layout() def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.accept() else: event.ignore() def dropEvent(self, event): files = [u.toLocalFile() for u in event.mimeData().urls()] for f in files: self.summarize_file(f) def zoomIn(self): ''' increases font size ''' size = self.central_widget.font().pointSize() self.central_widget.setFont(QFont(".AppleSystemUIFont", size + 2)) def zoomOut(self): ''' decreases font size ''' size = self.central_widget.font().pointSize() self.central_widget.setFont(QFont(".AppleSystemUIFont", size - 2))
class ReceiveDialog(Dialog): def __init__(self, parent=None, oklistener=None, address=None): width = 580 height = 230 title = "Receive Token" self.oklistener = oklistener self.address = address self.data() super().__init__(wallet.main_wnd, title=title, width=width, height=height) @component.data def data(self): return {"address": self.address} def close(self): app.event.emit(UPDATE) super().close() def show_copied(self): self.copied.show() def copy_address(self, _): clipboard = QApplication.clipboard() clipboard.setText(self.address.value) self.show_copied() def openUrl(self, url): try: webbrowser.get('chrome').open_new_tab(url) except: webbrowser.open_new_tab(url) def ui(self, widget): layout = QVBoxLayout(widget) row = QHBoxLayout() row.setSpacing(0) row.addWidget(Builder().text('Address:').name('address_hint').build()) row.addWidget(Builder().text( self.address.value).name('address').build()) row.addSpacing(10) picture = Picture(abs_path('icons/[email protected]'), width=30, height=30) picture.setObjectName('picture') row.addWidget(picture) row.addSpacing(8) row.addWidget(Builder().click( self.copy_address).text('Copy').name('copy').build()) row.addStretch(1) layout.addLayout(row) row2 = QHBoxLayout() row2.setSpacing(0) row2.addSpacing(15) row2.setAlignment(Qt.AlignBottom) qrcode = Picture(utils.get_cpc_free_qrcode(), width=96, height=96) qrcode.setObjectName('qrcode') row2.addWidget(qrcode) row2.addSpacing(10) copied_icon = Picture(abs_path('icons/[email protected]'), width=30, height=30) copied_layout = QHBoxLayout() copied_layout.setContentsMargins(0, 0, 0, 0) copied_layout.setSpacing(0) copied_layout.addWidget(copied_icon) copied_text = Builder().text('copied!').name('copied').build() copied_layout.addWidget(copied_text) copied_layout.addStretch(1) self.copied = QFrame(self) self.copied.setObjectName('copied_frame') self.copied.setLayout(copied_layout) vbox = QVBoxLayout() vbox.setContentsMargins(0, 0, 0, 0) vbox.setAlignment(Qt.AlignTop) vbox.addWidget(self.copied) row2.addLayout(vbox) self.copied.hide() row2.addStretch(1) layout.addLayout(row2) layout.addWidget( Builder().text('Get CPC for free').name('get_cpc').click( lambda _: self.openUrl(config.account.charge_server)).build()) return layout def style(self): return super().style() + """
class DolphinUpdate(QMainWindow): APP_TITLE = 'DolphinUpdate 3.1' DOWNLOAD_PATH = os.path.join(os.getenv('APPDATA'), 'DolphinUpdate/') def __init__(self, user_data_control): super().__init__() sys.excepthook = self._displayError self._udc = user_data_control self.check = QPixmap("res/check.png") self.cancel = QPixmap("res/cancel.png") self.setGeometry(500, 500, 500, 465) self.init_ui() self.init_window() self.init_user_data() self.setWindowTitle(self.APP_TITLE) self.setWindowIcon(QIcon('res/rabbit.png')) center(self) self.show() # PyQt Error Handling def _displayError(self, etype, evalue, etraceback): tb = ''.join(traceback.format_exception(etype, evalue, etraceback)) QMessageBox.critical(self, "FATAL ERROR", "An unexpected error occurred:\n%s\n\n%s" % (evalue, tb)) def init_ui(self): """create the UI elements in the main window""" self.statusBar().showMessage('Ready') main = QWidget() self.setCentralWidget(main) self.dolphin_dir = QLineEdit(main) self.dolphin_dir.setPlaceholderText("Please Select a Dolphin Directory") self.dolphin_dir.setReadOnly(True) self.version = QLineEdit(main) self.version.setPlaceholderText("Installation Status Unknown") self.version.setReadOnly(True) self.current = QLineEdit(main) self.current.setPlaceholderText("Loading Current Version...") self.current.setReadOnly(True) self.changelog_frame = QFrame(main) changelog_vbox = QVBoxLayout(self.changelog_frame) self.changelog = QTextBrowser(main) self.changelog.setPlaceholderText("Loading Changelog...") self.changelog.setReadOnly(True) changelog_vbox.addWidget(QLabel('Changelog:')) changelog_vbox.addWidget(self.changelog) self.changelog_frame.setContentsMargins(0, 20, -7, 0) grid = QGridLayout() main.setLayout(grid) self.dolphin_dir_status = QLabel(main) self.dolphin_dir_status.setPixmap(self.cancel) self.version_status = QLabel(main) self.version_status.setPixmap(self.cancel) self.current_status = QLabel(main) self.current_status.setPixmap(QPixmap("res/info.png")) grid.addWidget(self.dolphin_dir_status, 0, 0, Qt.AlignCenter) grid.addWidget(QLabel('Dolphin Directory:'), 0, 2) grid.addWidget(self.dolphin_dir, 0, 3) grid.addWidget(self.version_status, 1, 0, Qt.AlignCenter) grid.addWidget(QLabel('Your Version:'), 1, 2) grid.addWidget(self.version, 1, 3) grid.addWidget(self.current_status, 2, 0, Qt.AlignCenter) grid.addWidget(QLabel('Current Version:'), 2, 2) grid.addWidget(self.current, 2, 3) grid.addWidget(self.changelog_frame, 3, 0, 1, 4) grid.setSpacing(10) grid.setVerticalSpacing(2) grid.setRowStretch(3, 1) def init_window(self): self.update_thread = UpdateThread() self.update_thread.current.connect(self.update_current) self.update_thread.changelog.connect(self.update_changelog) self.update_thread.error.connect(self.show_warning) self.update_thread.start() self.download_thread = DownloadThread() self.download_thread.status.connect(self.update_version) self.download_thread.error.connect(self.show_warning) open_action = QAction(QIcon('res/open.png'), '&Open', self) open_action.setShortcut('Ctrl+O') open_action.setStatusTip('Select Dolphin Folder') open_action.triggered.connect(self.select_dolphin_folder) self.hide_changelog_action = QAction('Hide Changelog', self) self.hide_changelog_action.setStatusTip('Hide Changelog Section') self.hide_changelog_action.setCheckable(True) self.hide_changelog_action.toggled.connect(self.hide_changelog) self.hide_changelog_action.setChecked(self._udc.get_hide_changelog()) update_action = QAction(QIcon('res/synchronize.png'), '&Refresh', self) update_action.setStatusTip('Refresh Current Version') update_action.triggered.connect(self.retrieve_current) download_action = QAction(QIcon('res/download.png'), '&Download', self) download_action.setStatusTip('Download Newest Version') download_action.triggered.connect(self.download_new) clear_action = QAction(QIcon('res/delete.png'), '&Clear Version', self) clear_action.setStatusTip('Reset Your Version') clear_action.triggered.connect(self.clear_version) exit_action = QAction(QIcon('res/exit.png'), '&Exit', self) exit_action.setShortcut('Ctrl+Q') exit_action.setStatusTip('Exit application') exit_action.triggered.connect(self.close) launch_dolphin_action = QAction(QIcon('res/dolphin.png'), '&Launch Dolphin', self) launch_dolphin_action.setShortcut('Ctrl+D') launch_dolphin_action.setStatusTip('Launch Dolphin') launch_dolphin_action.triggered.connect(self.launch_dolphin) file_menu = self.menuBar().addMenu('&File') file_menu.addAction(open_action) file_menu.addAction(update_action) file_menu.addAction(clear_action) file_menu.addAction(launch_dolphin_action) file_menu.addAction(exit_action) file_menu = self.menuBar().addMenu('&View') file_menu.addAction(self.hide_changelog_action) toolbar = self.addToolBar('Toolbar') toolbar.addAction(open_action) toolbar.addAction(update_action) toolbar.addAction(download_action) toolbar.addSeparator() toolbar.addAction(launch_dolphin_action) settings_frame = QFrame() settings_form = QFormLayout(settings_frame) self.auto_launch_check = QCheckBox(settings_frame) self.auto_launch_check.setChecked(self._udc.get_auto_launch()) settings_form.addRow("Auto Launch?", self.auto_launch_check) self.launch_qt_check = QCheckBox(settings_frame) self.launch_qt_check.setChecked(self._udc.get_qt()) settings_form.addRow("Launch QT Version?", self.launch_qt_check) settings_form.setContentsMargins(0, 1, 2, 0) self.statusBar().addPermanentWidget(settings_frame) def launch_dolphin(self): dolphin_dir = self.dolphin_dir.text() if not dolphin_dir: self.show_warning('Please select a dolphin folder.') return if (self.launch_qt_check.isChecked() == False): dolphinexe = 'Dolphin.exe' else: dolphinexe = 'DolphinQt2.exe' dolphin_path = os.path.join(dolphin_dir, dolphinexe) if not os.path.isfile(dolphin_path): self.show_warning('Could not find "' + dolphinexe + '".') return subprocess.Popen(dolphin_path, cwd=dolphin_dir) self.close() def update_version(self, message): if message == 'finished': self.version.setText(self.version.placeholderText()) self.version.setPlaceholderText("Installation Status Unknown") self.version_status.setPixmap(self.check) self._udc.set_user_version(self.version.text()) if self.auto_launch_check.isChecked() and QApplication.keyboardModifiers() != Qt.ShiftModifier: QTimer.singleShot(1000, self.launch_dolphin) else: self.version.setPlaceholderText(message) def download_new(self): dolphin_dir = self.dolphin_dir.text() version = self.version.text() if self.current.text() == version: self.show_warning('You already have the most recent version.') return elif not os.path.isdir(dolphin_dir): self.show_warning('Your dolphin folder path is invalid.') self.dolphin_dir_status.setPixmap(QPixmap("res/cancel.png")) return if not self.download_thread.isRunning(): if dir == 'Please Select a Dolphin Directory': self.show_warning('Please select a dolphin folder.') self.version.setText('') self.download_thread.update(dolphin_dir, version) self.download_thread.start() def update_changelog(self, message): self.changelog.setText(message) def show_warning(self, message): QMessageBox.warning(self, 'Uh-oh', message, QMessageBox.Ok) def clear_version(self): reply = QMessageBox.question(self, 'Clear', "Are you sure you want to reset your version?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.version.setText('') self.version_status.setPixmap(self.cancel) self._udc.set_user_version('') def retrieve_current(self): if ~self.update_thread.isRunning(): self.current.setText('') self.update_thread.start() def update_current(self, current): self.current.setText(current) if self.version.text() == self.current.text(): self.version_status.setPixmap(self.check) if self.auto_launch_check.isChecked() and QApplication.keyboardModifiers() != Qt.ShiftModifier: QTimer.singleShot(1000, self.launch_dolphin) else: self.version_status.setPixmap(self.cancel) if self.auto_launch_check.isChecked() and self.dolphin_dir.text(): self.download_new() def select_dolphin_folder(self): folder = str(QFileDialog.getExistingDirectory(self, 'Select Dolphin Directory')) if folder: self.dolphin_dir.setText(folder) self.dolphin_dir_status.setPixmap(QPixmap("res/check.png")) self._udc.set_user_path(folder) def hide_changelog(self, checked): self._udc.set_hide_changelog(checked) if checked: self.setMinimumHeight(250) self.changelog_frame.hide() self.resize(500, 250) else: self.setMinimumHeight(375) self.resize(500, 465) self.changelog_frame.show() def init_user_data(self): """initialize the dolphin path""" path, version = self._udc.load_user_data() if path: self.dolphin_dir.setText(path) if os.path.isdir(path): self.dolphin_dir_status.setPixmap(self.check) if version: self.version.setText(version) # PyQt closeEvent called on exit def closeEvent(self, event): self._udc.set_auto_launch(self.auto_launch_check.isChecked()) self._udc.set_qt(self.launch_qt_check.isChecked()) if self.download_thread.isRunning(): event.ignore() reply = QMessageBox.question(self, 'Exit', "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.hide() self.download_thread.finished.connect(qApp.quit) else: event.accept()
class UISpritesheetExporter(object): def __init__(self): # here we don't need super().__init__(parent) # maybe it's only for who inherits extensions? self.app = krita.Krita.instance() self.exp = spritesheetexporter.SpritesheetExporter() # the main window self.mainDialog = QDialog() # the window is not modal and does not block input to other windows self.mainDialog.setWindowModality(Qt.NonModal) self.mainDialog.setMinimumSize(500, 100) # the box holding everything self.outerLayout = QVBoxLayout(self.mainDialog) self.topLayout = QVBoxLayout() # the user should choose the export name of the final spritesheet self.exportName = QLineEdit() # and the export directory self.exportDirTx = QLineEdit() self.exportDirButt = QPushButton("Change export directory") self.exportDirResetButt = QPushButton("Reset to current directory") self.exportDirResetButt.setToolTip( "Reset export directory to current .kra document's directory") self.exportDirButt.clicked.connect(self.changeExportDir) self.exportDirResetButt.clicked.connect(self.resetExportDir) self.exportDir = QHBoxLayout() # and the sprites export directory self.spritesExportDirWidget = QWidget() self.spritesExportDirTx = QLineEdit() self.spritesExportDirButt = QPushButton("Change sprites directory") self.spritesExportDirButt.clicked.connect(self.changeSpritesExportDir) self.spritesExportDirTx.setToolTip("Leave empty for default") self.spritesExportDir = QHBoxLayout(self.spritesExportDirWidget) self.customSettings = QCheckBox() self.customSettings.setChecked(False) self.customSettings.stateChanged.connect(self.toggleHideable) self.hideableWidget = QFrame() # QFrames are a type of widget self.hideableWidget.setFrameShape(QFrame.Panel) self.hideableWidget.setFrameShadow(QFrame.Sunken) self.hideableLayout = QVBoxLayout(self.hideableWidget) # we let people export each layer as an animation frame if they wish self.layersAsAnimation = QCheckBox() self.layersAsAnimation.setChecked(False) # We want to let the user choose if they want the final spritesheet # to be horizontally- or vertically-oriented. # There is a nifty thing called QButtonGroup() but # it doesn't seem to let you add names between each checkbox somehow? self.horDir = QCheckBox() self.horDir.setChecked(True) self.vertDir = QCheckBox() self.vertDir.setChecked(False) self.vertDir.stateChanged.connect(self.exclusiveVertToHor) self.horDir.stateChanged.connect(self.exclusiveHorToVert) self.direction = QHBoxLayout() self.spinBoxesWidget = QFrame() self.spinBoxesWidget.setFrameShape(QFrame.Panel) self.spinBoxesWidget.setFrameShadow(QFrame.Sunken) # a box holding the boxes with rows columns and start end self.spinBoxes = QHBoxLayout(self.spinBoxesWidget) self.rows = QSpinBox(minimum=self.exp.defaultSpace) self.columns = QSpinBox(minimum=self.exp.defaultSpace) self.rows.setValue(self.exp.defaultSpace) self.columns.setValue(self.exp.defaultSpace) self.start = QSpinBox(minimum=self.exp.defaultTime) self.end = QSpinBox(minimum=self.exp.defaultTime) self.step = QSpinBox(minimum=1) self.start.setValue(self.exp.defaultTime) self.end.setValue(self.exp.defaultTime) self.step.setValue(1) # to be placed outside of spinBoxes, still in outerLayout self.hiddenCheckbox = QWidget() self.hiddenCheckboxLayout = QVBoxLayout(self.hiddenCheckbox) self.line = QFrame() self.line.setFrameShape(QFrame.HLine) self.line.setFrameShadow(QFrame.Sunken) self.checkBoxes = QHBoxLayout() self.forceNew = QCheckBox() self.forceNew.setChecked(False) self.removeTmp = QCheckBox() self.removeTmp.setChecked(True) self.line2 = QFrame() self.line2.setFrameShape(QFrame.HLine) self.line2.setFrameShadow(QFrame.Sunken) self.OkCancelButtonBox = \ QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.OkCancelButtonBox.accepted.connect(self.confirmButton) self.OkCancelButtonBox.rejected.connect(self.mainDialog.close) self.space = 10 self.spacer = QSpacerItem(self.space, self.space) self.spacerBig = QSpacerItem(self.space * 2, self.space * 2) self.exportPath = Path.home() self.initialize_export() # I would have used QFormLayout's addRow # except it doesn't let you add a tooltip to the row's name # (adding a tooltip to the whole layout would have been best # but doesn't seem possible) def addDescribedWidget(self, parent, listWidgets, align=Qt.AlignLeft): layout = QGridLayout() row = 0 for widget in listWidgets: label = QLabel(widget.descri) label.setBuddy(widget.widget) layout.addWidget(label, row, 0) layout.addWidget(widget.widget, row, 1) if widget.tooltip != "": widget.widget.setToolTip(widget.tooltip) label.setToolTip(widget.tooltip) row += 1 layout.setAlignment(align) parent.addLayout(layout) return layout def initialize_export(self): # putting stuff in boxes # and boxes in bigger boxes self.exportName.setText(self.exp.exportName) self.addDescribedWidget( parent=self.topLayout, listWidgets=[ describedWidget( widget=self.exportName, descri="Export name:", tooltip="The name of the exported spritesheet file") ]) self.addDescribedWidget( parent=self.topLayout, listWidgets=[ describedWidget( widget=self.exportDirTx, descri="Export Directory:", tooltip="The directory the spritesheet will be exported to" ) ]) self.exportDir.addWidget(self.exportDirButt) self.exportDir.addWidget(self.exportDirResetButt) self.topLayout.addLayout(self.exportDir) self.addDescribedWidget( parent=self.topLayout, listWidgets=[ describedWidget( widget=self.customSettings, descri="Use Custom export Settings:", tooltip="" + "Whether to set yourself the number of rows, columns,\n" + "first and last frame, etc. (checked)\n" + "or use the default values (unchecked) ") ]) self.outerLayout.addLayout(self.topLayout, 0) # all this stuff will be hideable self.addDescribedWidget( parent=self.hideableLayout, listWidgets=[ describedWidget( descri="use layers as animation frames ", widget=self.layersAsAnimation, tooltip="Rather than exporting a spritesheet " + "using as frames\n" + "each frame of the timeline " + "(all visible layers merged down),\n" + "export instead a spritesheet " + "using as frames\n" + "the current frame of each visible layer") ]) self.hideableLayout.addItem(self.spacer) self.direction.addWidget(QLabel("sprites placement direction: \t")) self.addDescribedWidget( parent=self.direction, listWidgets=[ describedWidget(widget=self.horDir, descri="Horizontal:", tooltip="like so:\n1, 2, 3\n4, 5, 6\n7, 8, 9") ]) self.addDescribedWidget( parent=self.direction, listWidgets=[ describedWidget(widget=self.vertDir, descri="Vertical:", tooltip="like so:\n1, 4, 7\n2, 5, 8\n3, 6, 9") ]) self.hideableLayout.addLayout(self.direction) self.hideableLayout.addItem(self.spacerBig) defaultsHint = QLabel( "Leave any parameter at 0 to get a default value:") defaultsHint.setToolTip( "For example with 16 sprites, " + "leaving both rows and columns at 0\n" + "will set their defaults to 4 each\n" + "while leaving only columns at 0 and rows at 1\n" + "will set columns default at 16") self.hideableLayout.addWidget(defaultsHint) self.addDescribedWidget( parent=self.spinBoxes, listWidgets=[ describedWidget( widget=self.rows, descri="Rows:", tooltip="Number of rows of the spritesheet;\n" + "default is assigned depending on columns number\n" + "or if 0 columns tries to form a square "), describedWidget( widget=self.columns, descri="Columns:", tooltip="Number of columns of the spritesheet;\n" + "default is assigned depending on rows number\n" + "or if 0 rows tries to form a square") ]) self.addDescribedWidget( parent=self.spinBoxes, listWidgets=[ describedWidget( widget=self.start, descri="Start:", tooltip="" + "First frame of the animation timeline (included) " + "to be added to the spritesheet;\n" + "default is first keyframe after " + "the Start frame of the Animation docker"), describedWidget( widget=self.end, descri="End:", tooltip="Last frame of the animation timeline (included) " + "to be added to the spritesheet;\n" + "default is last keyframe before " + "the End frame of the Animation docker"), describedWidget(widget=self.step, descri="Step:", tooltip="only consider every 'step' frame " + "to be added to the spritesheet;\n" + "default is 1 (use every frame)") ]) self.hideableLayout.addWidget(self.spinBoxesWidget) self.addDescribedWidget( parent=self.checkBoxes, listWidgets=[ describedWidget( descri="Remove individual sprites?", widget=self.removeTmp, tooltip="Once the spritesheet export is done,\n" + "whether to remove the individual exported sprites") ]) self.forceNewLayout = self.addDescribedWidget( parent=self.hiddenCheckboxLayout, listWidgets=[ describedWidget( descri="Force new folder?", widget=self.forceNew, tooltip="If there is already a folder " + "with the same name as the individual " + "sprites export folder,\n" + "whether to create a new one (checked) " + "or write the sprites in the existing folder,\n" + "possibly overwriting other files (unchecked)") ]) self.addDescribedWidget( parent=self.spritesExportDir, listWidgets=[ describedWidget( widget=self.spritesExportDirTx, descri="Sprites export directory:", tooltip="The directory the individual sprites " + "will be exported to") ]) self.spritesExportDir.addWidget(self.spritesExportDirButt) # have removeTmp toggle forceNew's and sprites export dir's visibility self.checkBoxes.addWidget(self.hiddenCheckbox) self.hideableLayout.addLayout(self.checkBoxes) self.hideableLayout.addWidget(self.spritesExportDirWidget) self.removeTmp.clicked.connect(self.toggleHiddenParams) self.outerLayout.addWidget(self.hideableWidget) self.outerLayout.addWidget(self.OkCancelButtonBox) self.toggleHiddenParams() self.toggleHideable() def exclusiveVertToHor(self): self.exclusiveCheckBoxUpdate(trigger=self.vertDir, triggered=self.horDir) def exclusiveHorToVert(self): self.exclusiveCheckBoxUpdate(trigger=self.horDir, triggered=self.vertDir) def exclusiveCheckBoxUpdate(self, trigger, triggered): if triggered.isChecked() == trigger.isChecked(): triggered.setChecked(not trigger.isChecked()) def toggleHideable(self): if self.customSettings.isChecked(): self.hideableWidget.show() self.mainDialog.adjustSize() else: self.hideableWidget.hide() self.mainDialog.adjustSize() def toggleHiddenParams(self): if self.removeTmp.isChecked(): self.forceNew.setChecked(False) self.spritesExportDirTx.setText("") self.hiddenCheckbox.setDisabled(self.removeTmp.isChecked()) self.spritesExportDirWidget.setDisabled(self.removeTmp.isChecked()) def showExportDialog(self): self.doc = self.app.activeDocument() if self.exportDirTx.text() == "": self.resetExportDir() self.mainDialog.setWindowTitle(i18n("SpritesheetExporter")) self.mainDialog.setSizeGripEnabled(True) self.mainDialog.show() self.mainDialog.activateWindow() self.mainDialog.setDisabled(False) def changeExportDir(self): self.exportDirDialog = QFileDialog() self.exportDirDialog.setWindowTitle(i18n("Choose Export Directory")) self.exportDirDialog.setSizeGripEnabled(True) self.exportDirDialog.setDirectory(str(self.exportPath)) # we grab the output path on directory changed self.exportPath = self.exportDirDialog.getExistingDirectory() if self.exportPath != "": self.exportDirTx.setText(str(self.exportPath)) # go back to the same folder where your .kra is def resetExportDir(self): if self.doc and self.doc.fileName(): self.exportPath = Path(self.doc.fileName()).parents[0] self.exportDirTx.setText(str(self.exportPath)) def changeSpritesExportDir(self): self.SpritesExportDirDialog = QFileDialog() self.SpritesExportDirDialog.setWindowTitle( i18n("Choose Sprites Export Directory")) self.SpritesExportDirDialog.setSizeGripEnabled(True) self.SpritesExportDirDialog.setDirectory(str(self.exportPath)) # we grab the output path on directory changed self.spritesExportPath = \ self.SpritesExportDirDialog.getExistingDirectory() if self.spritesExportPath != "": self.spritesExportDirTx.setText(str(self.spritesExportPath)) def confirmButton(self): # if you double click it shouldn't interrupt # the first run of the function with a new one self.mainDialog.setDisabled(True) self.exp.exportName = self.exportName.text().split('.')[0] self.exp.exportDir = Path(self.exportPath) self.exp.layersAsAnimation = self.layersAsAnimation.isChecked() self.exp.isDirectionHorizontal = self.horDir.isChecked() self.exp.rows = self.rows.value() self.exp.columns = self.columns.value() self.exp.start = self.start.value() self.exp.end = self.end.value() self.exp.step = self.step.value() self.exp.removeTmp = self.removeTmp.isChecked() self.exp.forceNew = self.forceNew.isChecked() if self.spritesExportDirTx.text() != "": self.exp.spritesExportDir = Path(self.spritesExportDirTx.text()) else: # important: we reset spritesheetexporter's spritesExportDir self.exp.spritesExportDir = self.exp.defaultPath self.exp.export() self.mainDialog.hide()
class TestApp(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.studFrame = QFrame() self._s = Stud() self._s.setupUi(self.studFrame) self.settFrame = QFrame() self._set = Settings() self._set.setupUi(self.settFrame) self.info = self.ui.infoLine self.q1 = self.ui.question self.a_dic = { 1: self.ui.answer1, 2: self.ui.answer2, 3: self.ui.answer3, 4: self.ui.answer4, 5: self.ui.answer5 } self.ch_dic = { 1: self.ui.checkBox1, 2: self.ui.checkBox2, 3: self.ui.checkBox3, 4: self.ui.checkBox4, 5: self.ui.checkBox5 } self.next = self.ui.next self.print = self.ui.print self.open = self.ui.open self.settings = self.ui.settings self.exit = self.ui.exit self.about = self.ui.about self.bar = self.ui.statusbar self.btnStud = self._s.buttonBox self.lineStud = self._s.student self.next.clicked.connect(self.fileOpen) self.print.clicked.connect(self.printer) self.open.triggered.connect(self.fileOpen) self.settings.triggered.connect(self.settFrameShow) self.about.triggered.connect(self.aboutMenu) self.exit.triggered.connect(sys.exit) self.q1.hide() self.info.hide() self.print.hide() for a in self.a_dic.values(): a.hide() for ch in self.ch_dic.values(): ch.hide() self.rep_key = QShortcut(QtGui.QKeySequence("Ctrl+R"), self) self.rep_key.activated.connect(self.openRep) self.ui.centralwidget.setStyleSheet('background: url(bkgnd.png)') self.font1 = QFont("Comic Sans Ms", 20, QFont.DemiBold, QFont.AnyStyle) self.font2 = QFont("Arial Rounded MT Bold", 25, QFont.Bold) def fileOpen(self): # Open test file and create question-answer dictionary f_dialog = QFileDialog() f_dialog.setFileMode(QFileDialog.AnyFile) f_dialog.setNameFilter("Text (*.txt)") if f_dialog.exec_(): self.file_name = f_dialog.selectedFiles()[0] self.test = {} try: with open(self.file_name, 'r', encoding='utf-8') as f: lines = f.readlines() except Exception: with open(self.file_name, 'r', encoding='cp1251') as f: lines = f.readlines() pass for line in lines: try: if not 'Name' in lines[0]: self.test_name = 'Не найдено название теста' elif 'Name' in line[:5]: self.test_name = line[6:] except Exception: pass n = 0 t = [] test_dic = dict.fromkeys( ('Qs', 'A1', 'A2', 'A3', 'A4', 'A5', 'An'), 0) for line in lines: for k in test_dic.keys(): if k in line[:3]: t.append(line) if 'An' in line[:3]: self.test.update({n: t}) n += 1 t = [] self.q1.show() self.q1.setText("\n\n" + self.test_name) self.q1.setStyleSheet("") self.q1.setFrameStyle(QFrame.NoFrame) self.next.clicked.disconnect() self.next.setText('Далее') self.next.clicked.connect(self.studSet) self.print.hide() self.ui.menubar.hide() self.ui.centralwidget.setStyleSheet('background: url(bkgnd.png)') else: self.close() def studSet(self): # Student name input frame self.studFrame.show() application.hide() self.next.clicked.disconnect() self.btnStud.accepted.connect(self.testInit) self.btnStud.rejected.connect(self.studFrame.hide) self.btnStud.rejected.connect(self.close) def testInit(self): self.settRead() # Define variables self.fin = False self.q_num_list = [] self.result = 0 self.percent = 0 self.q_count = 0 self.spent_time = False self.student = self.lineStud.text().title() try: # Check if questions in settings not exceed questions in self.test dictionary if self.q_try > len(self.test): self.q_try = len(self.test) # Vars for messagebar (random and color) if self.rand: self.ifrand = 'ВКЛ' else: self.ifrand = 'ОТКЛ' if self.color: self.ifcolor = 'ВКЛ' else: self.ifcolor = 'ОТКЛ' self.studFrame.hide() application.show() self.q1.setFont(self.font1) self.q1.setText("\n\n\n" + self.student + ", желаю удачи в прохождении теста:\n" + self.test_name) self.next.setText("Поехали!") self.next.clicked.connect(self.testMain) except Exception as e: pass def testMain(self): if not self.spent_time: self.start_time = time.time() self.timeSpent() self.info.hide() for a in self.a_dic.values(): a.hide() for ch in self.ch_dic.values(): ch.hide() ch.setChecked(False) if self.q_try: if not self.rand: self.q_num = self.q_count else: self.q_num = random.choice(list(self.test)) if self.q_num in self.q_num_list: while self.q_num in self.q_num_list: self.q_num = random.choice(list(self.test)) self.q_num_list.append(self.q_num) try: tek = self.test[self.q_num] question = tek[0][3:] frame = 1 for k, a in self.a_dic.items(): try: tek_a = tek[k] if 'An' in tek_a: pass else: a.setText(tek_a[3:]) frame += 1 except IndexError: pass key = [int(i) for i in tek[-1][3:].split()] key.sort() for i in range(1, frame): a = self.a_dic[i] a.show() a.setStyleSheet("") ch = self.ch_dic[i] ch.show() self.q1.setFont(self.font2) self.q1.setText(question) if len(key) > 1: self.info.setText('Выберите несколько вариантов ответа') elif len(key) <= 1: self.info.setText('Выберите один вариант ответа') self.info.show() self.q1.setFrameShape(QFrame.WinPanel) self.q1.setStyleSheet("background-color:rgb(91, 213, 89)") self.ui.centralwidget.setStyleSheet(" ") self.next.setText("Далее") self.next.clicked.disconnect() self.next.clicked.connect(lambda: self.answerCheck(key)) except KeyError: tek = ['*** No more question', '', '', '', ''] self.finish() else: self.finish() def answerCheck(self, key): self.q_count += 1 self.q_try -= 1 answer = [] for k, v in self.ch_dic.items(): if v.isChecked(): answer.append(k) if key == answer: self.result += 1 else: self.q1.setStyleSheet("background-color: rgb(255, 0, 0)") if self.color == 1: for i in key: a = self.a_dic[i] a.setStyleSheet("background-color:rgb(91, 213, 89)") if self.q_count == 0: p = 0 else: p = self.result * 100 / self.q_count self.percent = float("%.1f" % p) QTimer.singleShot(self.color_time * 1000, self.testMain) def finish(self): self.fin = True for a in self.a_dic.values(): a.hide() for ch in self.ch_dic.values(): ch.hide() self.day = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) if self.percent >= self.mark_5: self.mark = '5' elif self.percent >= self.mark_4: self.mark = '4' elif self.percent >= self.mark_3: self.mark = '3' elif self.percent >= self.mark_2: self.mark = '2' else: self.mark = '1' if int(self.mark) > 3: self.q1.setStyleSheet("background-color:rgb(91, 213, 89)") else: self.q1.setStyleSheet("background-color: rgb(255, 0, 0)") self.rep = ("Дата: " + self.day + "\nТестируемый: " + self.student + "\nТема: " + self.test_name + "\nПравильных ответов: " + str(self.result) + "\nВсего вопросов: " + str(self.q_count) + "\nЗатрачено времени: " + str(self.spent_time) + " мин." "\nРезультативность: " + str(self.percent) + "%" "\nОценка: " + self.mark + "\n\n") with open('report.txt', 'a', encoding='utf-8') as f_rep: f_rep.write(self.rep) self.q1.setText(self.rep) self.next.show() self.print.show() self.next.clicked.disconnect() self.next.setText("Закончить") self.next.clicked.connect(self.close) self.ui.menubar.show() def openRep(self): try: subprocess.Popen(['notepad.exe', r'report.txt']) except Exception as e: self.q1.show() self.q1.setText(str(e)) def settFrameShow(self): self.settRead() try: if self.color == 1: self._set.colBox.setChecked(True) self._set.colTimeLine.setText(str(self.color_time)) if self.rand == 1: self._set.ranBox.setChecked(True) self._set.tryLine.setText(str(self.q_try)) self._set.mark5Line.setText(str(self.mark_5)) self._set.mark4Line.setText(str(self.mark_4)) self._set.mark3Line.setText(str(self.mark_3)) self._set.mark2Line.setText(str(self.mark_2)) self.settFrame.show() self._set.buttonBox.accepted.connect(self.settWrite) self._set.buttonBox.rejected.connect(self.settFrame.close) except Exception as e: pass def settWrite(self): if self._set.colBox.isChecked(): self.color = 1 self.color_time = self._set.colTimeLine.text() else: self.color = 0 self.color_time = 0 if self._set.ranBox.isChecked(): self.rand = 1 else: self.rand = 0 self.q_try = self._set.tryLine.text() self.mark_5 = self._set.mark5Line.text() self.mark_4 = self._set.mark4Line.text() self.mark_3 = self._set.mark3Line.text() self.mark_2 = self._set.mark2Line.text() settings = [ self.color, self.color_time, self.rand, self.q_try, self.mark_5, self.mark_4, self.mark_3, self.mark_2 ] with open("settings.ini", "w", encoding='utf-8') as f: for i in settings: f.write("%s " % i) self.settFrame.close() def settRead(self): # Settings read from ini file try: with open('settings.ini', 'r', encoding='utf-8') as f: line = f.readline().split() line = [int(l) for l in line] self.color = line[0] self.color_time = line[1] self.rand = line[2] self.q_try = line[3] self.mark_5 = line[4] self.mark_4 = line[5] self.mark_3 = line[6] self.mark_2 = line[7] except Exception as e: self.settFrame.show() self._set.buttonBox.accepted.connect(self.settWrite) self._set.buttonBox.rejected.connect(self.settFrame.close) def timeSpent(self): if not self.fin: t = int(time.time()) - int(self.start_time) if t >= 60: tm = int(t / 60) ts = t - tm * 60 else: tm = 0 ts = t if ts < 10: self.spent_time = str(tm) + ":0" + str(ts) else: self.spent_time = str(tm) + ":" + str(ts) self.bar.showMessage("Время " + self.spent_time + " Тест: " + self.test_name + " Вопрос №" + str(self.q_count + 1) + " Результат: " + str(self.percent) + "% Студент " + self.student + " Вопросов " + str(self.q_try) + " Случайно " + self.ifrand + " Контроль " + self.ifcolor) QTimer.singleShot(500, self.timeSpent) else: self.bar.showMessage(" ") def printer(self): with open('temp.txt', 'w', encoding='utf-8') as f: f.write(self.rep) os.startfile("temp.txt", "print") time.sleep(3) os.remove("temp.txt") def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: try: self.finish() except AttributeError: pass self.close() def aboutMenu(self): self.q1.setFont(self.font1) self.q1.show() self.q1.setText( 'Программа для тестирования была написана для проведения проверки знаний у персонала ГП "Кыргызаэронавигация"\n' 'Настройка и использование программы не должны вызвать каких-либо затруднений. Для настройки нажмите "Меню"' '-> "Настройки"\nВ случае возникновения вопросов прошу обращаться.\n\nРазработчик: Мамутов А' )
class CallTips(QFrame): def __init__(self, parent): super().__init__(parent) self.setFrameStyle(QFrame.StyledPanel) layout = QVBoxLayout(self) layout.setContentsMargins(2, 2, 2, 2) palette = self.palette() palette.setColor(QPalette.Window, QColor("#fff")) self.setPalette(palette) self.setWindowFlags(Qt.ToolTip) self.line = QFrame(self) self.line.setFrameShape(QFrame.HLine) self.line.setFrameShadow(QFrame.Sunken) self.title_label = QLabel() self.title_label.setMinimumWidth(300) self.title_label.setFont(parent.font()) self.docstring_textedit = QTextEdit(self) self.docstring_textedit.setReadOnly(True) self.docstring_textedit.setFont(parent.font()) palette = self.docstring_textedit.palette() palette.setColor(QPalette.WindowText, QColor("#888")) palette.setColor(QPalette.Text, QColor("#888")) self.docstring_textedit.setPalette(palette) self.docstring_textedit.setFrameShape(QFrame.NoFrame) self.docstring_textedit.document().setDocumentMargin(0) self.title_label.setPalette(palette) layout.setSpacing(2) layout.addWidget(self.title_label) layout.addWidget(self.line) layout.addWidget(self.docstring_textedit) layout.setSizeConstraint(QVBoxLayout.SetFixedSize) @staticmethod def signature_to_string(signature): name = signature.name params = [] for i, param in enumerate(signature.params): try: type_hint = param.get_type_hint() except TypeError: type_hint = None if signature.index == i: if type_hint: params.append( f'<b><u><font color="royalblue">{param.name}</font></u></b>: {type_hint}' ) else: params.append( f'<b><u><font color="royalblue">{param.name}</font></u></b>' ) else: if type_hint: params.append(f"{param.name}: {type_hint}") else: params.append(param.name) html = f'{name}({", ".join(params)})' docstring = "" if signature.docstring(True, True): docstring = signature.docstring(True, True).replace("\n", "<br>") return html, docstring def show_signatures(self, signatures, pos: QPoint): signature = signatures[0] text, docstring = self.signature_to_string(signature) self.title_label.setText(text) if not docstring: self.docstring_textedit.hide() self.line.hide() else: self.docstring_textedit.show() self.line.show() self.docstring_textedit.setHtml(docstring) self.docstring_textedit.document().adjustSize() height = self.docstring_textedit.document().size().height() self.docstring_textedit.setFixedHeight(min(150, height)) point = self.parent().mapToGlobal( QPoint(pos.x(), pos.y() - self.sizeHint().height() - 2) ) self.show() self.move(point.x(), point.y()) self.docstring_textedit.setStyleSheet(SCROLL_STYLESHEET)
class Principale(QWidget): def __init__(self): super().__init__() self.form_ordinateur = FormOrdinateur() self.selected_scenario_btn = None self.setUI() # Génère l'interface utilisateur def setUI(self): base = QVBoxLayout() top = QHBoxLayout() # Moitié haute de la fenêtre : 2 colonnes (liste des ordinateurs; liste des scénarios) col_top_left = QVBoxLayout() col_top_right = QVBoxLayout() col_top_left.addWidget(self.partial_scenarios()) col_top_right.addWidget(self.partial_ordinateurs()) top.addLayout(col_top_left, 1) top.addLayout(col_top_right, 1) base.addLayout(top) # Moitié basse : Log récapitulatif déroulement scénario base.addWidget(self.partial_result()) self.setLayout(base) self.setGeometry(300,300,800,600) self.setWindowTitle('AICToolbox') self.show() # Colonne de gauche def partial_ordinateurs(self): group = QGroupBox("Sélectionner un poste") vbox = QVBoxLayout() # Liste des ordinateurs (boutons) self.grille_ordinateurs = utils.AutoGridLayout() for ordinateur in services.book.ordinateurs: btn = utils.OrdinateurButton(ordinateur) btn.clicked.connect(self.clicked_btn_ordinateur) self.grille_ordinateurs.autoAddWidget(btn) vbox.addLayout(self.grille_ordinateurs) vbox.addStretch(1) # Formulaire ajout d'un ordinateur self.form_ordinateur = FormOrdinateur() vbox.addLayout(self.form_ordinateur) btn_add_ordinateur = QPushButton("Ajouter") btn_add_ordinateur.clicked.connect(self.clicked_btn_add_ordinateur) vbox.addWidget(btn_add_ordinateur) group.setLayout(vbox) return group # Colonne de droite def partial_scenarios(self): group = QGroupBox("Scénario") vbox = QVBoxLayout() form_scenario = self.partial_scenarios_form() form_scenario.hide() vbox.addLayout(self.partial_scenarios_list()) vbox.addStretch(1) vbox.addWidget(form_scenario) group.setLayout(vbox) return group # Liste des scénarios def partial_scenarios_list(self): grille = utils.AutoGridLayout() for scenario in scenarios.scenarios: btn = utils.ScenarioButton(scenario) btn.clicked.connect(self.clicked_btn_scenario) grille.autoAddWidget(btn) return grille # Label + conteneur formulaire scénario def partial_scenarios_form(self): self.form_scenario_frame = QFrame() vbox = QVBoxLayout() vbox.addWidget(QLabel("Paramètres du scénario")) self.form_scenario_container = QStackedLayout() vbox.addLayout(self.form_scenario_container) self.form_scenario_frame.setLayout(vbox) return self.form_scenario_frame # Moitié basse : log déroulement scénario def partial_result(self): group = QGroupBox("Résultat") self.console = ResultConsole() group.setLayout(self.console) return group def clicked_btn_ordinateur(self): sender = self.sender() # Empêche de décocher un bouton sender.setChecked(True) ordinateur = sender.ordinateur if (self.selected_scenario_btn): scenario = self.selected_scenario_btn.scenario self.run_scenario(scenario, ordinateur) def clicked_btn_scenario(self): if (self.selected_scenario_btn): self.selected_scenario_btn.setChecked(False) sender = self.sender() # Empêche de décocher un bouton sender.setChecked(True) self.selected_scenario_btn = sender # Initialisation du scénario scenario = sender.scenario if (scenario.form): self.form_scenario_frame.show() self.form_scenario_container.addWidget(scenario.form) self.form_scenario_container.setCurrentIndex(1) else: self.form_scenario_frame.hide() def clicked_btn_add_ordinateur(self): form = self.form_ordinateur ordinateur = form.to_ordinateur() services.book.add(ordinateur) btn = utils.OrdinateurButton(ordinateur) btn.clicked.connect(self.clicked_btn_ordinateur) self.grille_ordinateurs.autoAddWidget(btn) form.reset() def run_scenario(self, scenario, ordinateur): self.console.new_run(scenario, ordinateur) try: result = scenario.run(ordinateur) except invoke_exp.UnexpectedExit as err: if (err.result.stderr): self.console.new_error(err.result.stderr) else: self.console.new_error(err.result.stdout) except Exception as err: self.console.new_error(str(err)) else: self.console.end_run(result.stdout)
class GraphicalInterface(QMainWindow, Interface): def __init__(self, video_player, debug=False): self.__app = QApplication(sys.argv) super().__init__() self.__video_player = video_player #TODO get in .config the value of the volume by default self.__video_player.set_volume(100) # Property of the main window self.__width = 0 self.__height = 0 # List of all derivated object from the following QWidgets self.__palette = None self.__logo_image = None self.__previousbtn_image = None self.__skipbtn_image = None self.__playbtn_image = None self.__pausebtn_image = None # List of all the QWidget present in the main window self.__videotitle = None self.__searchbtn = None self.__searchbar = None self.__mainbox = None self.__modebox = None self.__logo = None self.__video_reader = None self.__previousbtn_audio = None self.__playbtn_audio = None self.__skipbtn_audio = None self.__previousbtn_video = None self.__playbtn_video = None self.__skipbtn_video = None self.__buttonbar_video = None # List of all the GraphicalObject in the main window self.__header = None self.__footer = None self.__body = None self.__gr_videotitle = None self.__gr_searchbar = None self.__gr_searchbtn = None self.__gr_modebox = None self.__gr_logo = None self.__gr_video_reader = None self.__gr_buttonbar_video = None self.__gr_previousbtn_audio = None self.__gr_playbtn_audio = None self.__gr_skipbtn_audio = None self.__gr_previousbtn_video = None self.__gr_playbtn_video = None self.__gr_skipbtn_video = None self.__object_list = [] self.__debug = debug def main(self): """ Main loop of the graphic interface """ self.resize(640, 480) self.move(0, 0) self.setWindowTitle('Youtube Reader') self.setWindowIcon(QIcon('resources/icon.svg')) content = read_css("./css/main.css") self.setStyleSheet(content) self.__mainbox = GraphicalObject(self, width=640, height=480, pos_x=0, pos_y=0) self.__header = GraphicalObject(None, width=100, height=10, pos_x=0, pos_y=0, parent=self.__mainbox) self.__searchbar = QLineEdit(self) self.__searchbar.returnPressed.connect(self.handle_research) self.__gr_searchbar = GraphicalObject(self.__searchbar, width=70, height=60, pos_x=15, pos_y=20, parent=self.__header) self.__searchbtn = QPushButton('Search', self) self.__searchbtn.clicked.connect(self.handle_research) self.__gr_searchbtn = GraphicalObject(self.__searchbtn, width=10, height=60, pos_x=87, pos_y=20, parent=self.__header) self.__logo_image = QPixmap('resources/logo.png') self.__logo = QLabel(self) self.__logo.setScaledContents(True) self.__logo.setPixmap(self.__logo_image) self.__gr_logo = GraphicalObject(self.__logo, width=15, height=60, pos_x=0, pos_y=20, parent=self.__header) self.__body = GraphicalObject(None, width=100, height=80, pos_x=0, pos_y=10, parent=self.__mainbox) self.create_reader() self.set_player_mode(self.__video_player.get_mode()) self.__footer = GraphicalObject(None, width=100, height=10, pos_x=0, pos_y=90, parent=self.__mainbox) self.__modebox = ComboDemo(self, self) self.__modebox.init_combo_box(self.__video_player.get_mode()) self.__gr_modebox = GraphicalObject(self.__modebox, width=20, height=100, pos_x=80, pos_y=20, parent=self.__footer) self.show() self.__app.exec_() self.__video_player.stop_stream() def handle_research(self): my_string = self.__searchbar.text() self.__searchbar.clear() if "www.youtube.com/" in my_string: self.__video_player.add_url(my_string) else: print("Search functionnality not implemented yet. Put url please!") def create_reader(self): # code from github.com/devos50/vlc-pyqt5-example.git # Video UI if sys.platform == "darwin": from PyQt5.QtWidgets import QMacCocoaViewContainer self.__video_reader = QMacCocoaViewContainer(0) else: self.__video_reader = QFrame(self) self.__palette = self.__video_reader.palette() self.__palette.setColor(QPalette.Window, QColor(0, 0, 0)) self.__video_reader.setPalette(self.__palette) self.__video_reader.setAutoFillBackground(True) self.__gr_video_reader = GraphicalObject(self.__video_reader, width=80, height=80, pos_x=10, pos_y=10, parent=self.__body) self.__videotitle = QLabel("No Video!", self) self.__videotitle.setWordWrap(True) self.__gr_videotitle = GraphicalObject(self.__videotitle, width=80, height=10, pos_x=10, pos_y=90, parent=self.__body) number_of_button = 3 btn_height = 7 btn_width = 7 ui_origin_x = 0 ui_origin_y = 100 - btn_height self.__buttonbar_video = QLabel(self) self.__buttonbar_video.setStyleSheet( "QLabel { background-color : white; color : blue; }") self.__gr_buttonbar_video = GraphicalObject( self.__buttonbar_video, width=100, height=btn_height, pos_x=0, pos_y=ui_origin_y, parent=self.__gr_video_reader) self.__previousbtn_video = TranslucidButton(self) self.__previousbtn_image = QPixmap('resources/back.svg') self.__previousbtn_video.setScaledContents(True) self.__previousbtn_video.setPixmap(self.__previousbtn_image) self.__gr_previousbtn_video = GraphicalObject( self.__previousbtn_video, width=btn_width, height=btn_height, pos_x=ui_origin_x + 0 * btn_width, pos_y=ui_origin_y, parent=self.__gr_video_reader) self.__skipbtn_video = TranslucidButton(self) self.__skipbtn_image = QPixmap('resources/skip.svg') self.__skipbtn_video.setScaledContents(True) self.__skipbtn_video.setPixmap(self.__skipbtn_image) self.__gr_skipbtn_video = GraphicalObject( self.__skipbtn_video, width=btn_width, height=btn_height, pos_x=ui_origin_x + 2 * btn_width, pos_y=ui_origin_y, parent=self.__gr_video_reader) self.__playbtn_video = TranslucidButton(self) self.__playbtn_video.clicked.connect(self.video_play_pause) self.__playbtn_image = QPixmap('resources/play.svg') self.__playbtn_video.setScaledContents(True) self.__playbtn_video.setPixmap(self.__playbtn_image) self.__gr_playbtn_video = GraphicalObject( self.__playbtn_video, width=btn_width, height=btn_height, pos_x=ui_origin_x + 1 * btn_width, pos_y=ui_origin_y, parent=self.__gr_video_reader) # Audio UI number_of_button = 3 btn_height = 5 btn_width = 10 ui_origin_x = 30 ui_origin_y = 50 - (btn_height / 2) self.__previousbtn_audio = QPushButton('Previous', self) #clicked.connect(self.handle_research) self.__gr_previousbtn_audio = GraphicalObject( self.__previousbtn_audio, width=btn_width, height=btn_height, pos_x=ui_origin_x + (0 * (100 - 2 * ui_origin_x)) / number_of_button, pos_y=ui_origin_y, parent=self.__body) self.__playbtn_audio = QPushButton('Play', self) self.__playbtn_audio.clicked.connect(self.audio_play_pause) self.__gr_playbtn_audio = GraphicalObject( self.__playbtn_audio, width=btn_width, height=btn_height, pos_x=ui_origin_x + (1 * (100 - 2 * ui_origin_x)) / number_of_button, pos_y=ui_origin_y, parent=self.__body) self.__skipbtn_audio = QPushButton('Skip', self) self.__skipbtn_audio.clicked.connect(self.__video_player.skip) self.__gr_skipbtn_audio = GraphicalObject( self.__skipbtn_audio, width=btn_width, height=btn_height, pos_x=ui_origin_x + (2 * (100 - 2 * ui_origin_x)) / number_of_button, pos_y=ui_origin_y, parent=self.__body) def set_player_mode(self, value): self.__video_player.set_mode(value) if value == 'Video': self.__video_reader.show() self.__previousbtn_audio.hide() self.__playbtn_audio.hide() self.__skipbtn_audio.hide() else: self.__video_reader.hide() self.__previousbtn_audio.show() self.__playbtn_audio.show() self.__skipbtn_audio.show() def end_of_play_list(self): print("End of stream") self.__palette.setColor(QPalette.Window, QColor(0, 0, 0)) self.__video_reader.setPalette(self.__palette) def update_title(self, title): self.__videotitle.setText(title) def audio_play_pause(self): if self.__video_player.is_running(): self.pause_start() else: self.__playbtn_audio.setText('Pause') self.__video_player.play_stream() def video_play_pause(self): print("Play pause") if self.__video_player.is_running(): self.pause_start() else: print("Launching the stream") if sys.platform.startswith( 'linux'): # for Linux using the X Server self.__video_player.get_player().set_xwindow( self.__video_reader.winId()) elif sys.platform == "win32": # for Windows self.__video_player.get_player().set_hwnd( self.__video_reader.winId()) elif sys.platform == "darwin": # for MacOS self.__video_player.get_player().set_nsobject( int(self.__video_reader.winId())) #TODO LAPALETTE self.__video_player.play_stream() if self.__video_player.is_playing(): self.__palette.setColor(QPalette.Window, QColor(255, 255, 255)) self.__video_reader.setPalette(self.__palette) self.__video_reader.setAutoFillBackground(True) def pause_start(self): if self.__video_player.is_paused(): print("Unpausing the player") self.__playbtn_audio.setText('Pause') self.__video_player.resume_stream() elif self.__video_player.is_playing(): print("Pausing the player") self.__playbtn_audio.setText('Play') self.__video_player.pause_stream() else: print("Restarting the stream") self.__playbtn_audio.setText('Pause') self.__video_player.play_stream() # Redefinition of the QMainWindow built-in methods def mousePressEvent(self, event): # Left click if event.button() == 1: if ((event.x() <= (self.__gr_video_reader.getRealWidth() + self.__gr_video_reader.getRealPosX())) and (event.x() >= self.__gr_video_reader.getRealPosX()) and (event.y() <= (self.__gr_video_reader.getRealHeight() + self.__gr_video_reader.getRealPosY())) and (event.y() >= self.__gr_video_reader.getRealPosY()) and self.__video_player.get_mode() == 'Video'): print("True") if self.__video_player.is_running(): self.pause_start() else: print("Launching the stream") if sys.platform.startswith( 'linux'): # for Linux using the X Server self.__video_player.get_player().set_xwindow( self.__video_reader.winId()) elif sys.platform == "win32": # for Windows self.__video_player.get_player().set_hwnd( self.__video_reader.winId()) elif sys.platform == "darwin": # for MacOS self.__video_player.get_player().set_nsobject( int(self.__video_reader.winId())) #TODO LAPALETTE self.__video_player.play_stream() if self.__video_player.is_playing(): self.__palette.setColor(QPalette.Window, QColor(255, 255, 255)) self.__video_reader.setPalette(self.__palette) self.__video_reader.setAutoFillBackground(True) print("Plop X " + str(event.x()) + " Plop Y " + str(event.y())) print("Glob X " + str(event.globalX()) + " Glob Y " + str(event.globalY())) def resizeEvent(self, event): print("OLD height: " + str(event.oldSize().height()) + " width: " + str(event.oldSize().width())) print("NEW height: " + str(event.size().height()) + " width: " + str(event.oldSize().width())) self.__width = event.size().width() self.__height = event.size().height() self.__mainbox.resize(event.size().width(), event.size().height())
class GcodeEditor(QWidget, _HalWidgetBase): percentDone = pyqtSignal(int) def __init__(self, parent=None): super(GcodeEditor, self).__init__(parent) self.isCaseSensitive = 0 self.setMinimumSize(QSize(300, 200)) self.setWindowTitle("PyQt5 editor test example") lay = QVBoxLayout() lay.setContentsMargins(0,0,0,0) self.setLayout(lay) # make editor self.editor = GcodeDisplay(self) # class patch editor's function to ours # so we get the lines percent update self.editor.emit_percent = self.emit_percent self.editor.setReadOnly(True) ################################ # add menubar actions ################################ # Create new action newAction = QAction(QIcon.fromTheme('document-new'), 'New', self) newAction.setShortcut('Ctrl+N') newAction.setStatusTip('New document') newAction.triggered.connect(self.newCall) # Create open action openAction = QAction(QIcon.fromTheme('document-open'), '&Open', self) openAction.setShortcut('Ctrl+O') openAction.setStatusTip('Open document') openAction.triggered.connect(self.openCall) # Create save action saveAction = QAction(QIcon.fromTheme('document-save'), '&save', self) saveAction.setShortcut('Ctrl+S') saveAction.setStatusTip('save document') saveAction.triggered.connect(self.saveCall) # Create exit action exitAction = QAction(QIcon.fromTheme('application-exit'), '&Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.exitCall) # Create gcode lexer action gCodeLexerAction = QAction(QIcon.fromTheme('lexer.png'), '&Gcode\n lexer', self) gCodeLexerAction.setCheckable(1) gCodeLexerAction.setShortcut('Ctrl+G') gCodeLexerAction.setStatusTip('Set Gcode highlighting') gCodeLexerAction.triggered.connect(self.editor.set_gcode_lexer) # Create gcode lexer action pythonLexerAction = QAction(QIcon.fromTheme('lexer.png'), '&python\n lexer', self) pythonLexerAction.setShortcut('Ctrl+P') pythonLexerAction.setStatusTip('Set Python highlighting') pythonLexerAction.triggered.connect(self.editor.set_python_lexer) # Create toolbar and add action toolBar = QToolBar('File') toolBar.addAction(newAction) toolBar.addAction(openAction) toolBar.addAction(saveAction) toolBar.addAction(exitAction) toolBar.addSeparator() # add lexer actions toolBar.addAction(gCodeLexerAction) toolBar.addAction(pythonLexerAction) toolBar.addSeparator() toolBar.addWidget(QLabel('<html><head/><body><p><span style=" font-size:20pt; font-weight:600;">Edit Mode</span></p></body></html>')) # create a frame for buttons box = QHBoxLayout() box.addWidget(toolBar) self.topMenu = QFrame() self.topMenu.setLayout(box) # add widgets lay.addWidget(self.topMenu) lay.addWidget(self.editor) lay.addWidget(self.createGroup()) self.readOnlyMode() def createGroup(self): self.bottomMenu = QFrame() self.searchText = QLineEdit(self) self.replaceText = QLineEdit(self) toolBar = QToolBar() # Create new action undoAction = QAction(QIcon.fromTheme('edit-undo'), 'Undo', self) undoAction.setStatusTip('Undo') undoAction.triggered.connect(self.undoCall) toolBar.addAction(undoAction) # create redo action redoAction = QAction(QIcon.fromTheme('edit-redo'), 'Redo', self) redoAction.setStatusTip('Undo') redoAction.triggered.connect(self.redoCall) toolBar.addAction(redoAction) toolBar.addSeparator() # create replace action replaceAction = QAction(QIcon.fromTheme('edit-find-replace'), 'Replace', self) replaceAction.triggered.connect(self.replaceCall) toolBar.addAction(replaceAction) # create find action findAction = QAction(QIcon.fromTheme('edit-find'), 'Find', self) findAction.triggered.connect(self.findCall) toolBar.addAction(findAction) # create next action nextAction = QAction(QIcon.fromTheme('go-previous'), 'Find Previous', self) nextAction.triggered.connect(self.nextCall) toolBar.addAction(nextAction) toolBar.addSeparator() # create case action caseAction = QAction(QIcon.fromTheme('edit-case'), 'Aa', self) caseAction.setCheckable(1) caseAction.triggered.connect(self.caseCall) toolBar.addAction(caseAction) box = QHBoxLayout() box.addWidget(toolBar) box.addWidget(self.searchText) box.addWidget(self.replaceText) box.addStretch(1) self.bottomMenu.setLayout(box) return self.bottomMenu def _hal_init(self): # name the top and bottom frames so it's easier to style #print '%sBottomButtonFrame'% self.objectName() self.bottomMenu.setObjectName('%sBottomButtonFrame'% self.objectName()) self.topMenu.setObjectName('%sTopButtonFrame'% self.objectName()) def editMode(self): self.topMenu.show() self.bottomMenu.show() self.editor.setReadOnly(False) def readOnlyMode(self): self.topMenu.hide() self.bottomMenu.hide() self.editor.setReadOnly(True) def openCall(self): print('Open') f = self.getFileName() self.editor.load_text(f) self.editor.setModified(False) def saveCall(self): print('save') self.saveFile() def newCall(self): if self.editor.isModified(): result = self.killCheck() if result: self.editor.new_text() def exitCall(self): print('Exit app') if self.editor.isModified(): result = self.killCheck() if result: self.readOnlyMode() def undoCall(self): self.editor.undo() def redoCall(self): self.editor.redo() def replaceCall(self): self.editor.replace_text(str(self.replaceText.text())) def findCall(self): self.editor.search(str(self.searchText.text()), re=False, case=self.isCaseSensitive, word=False, wrap= False, fwd=True) def nextCall(self): self.editor.search(str(self.searchText.text()),False) self.editor.search_Next() def caseCall(self): self.isCaseSensitive -=1 self.isCaseSensitive *=-1 print self.isCaseSensitive def getFileName(self): name = QFileDialog.getOpenFileName(self, 'Open File') return str(name[0]) def killCheck(self): choice = QMessageBox.question(self, 'Warning!!', "This file has changed since loading...Still want to proceed?", QMessageBox.Yes | QMessageBox.No) if choice == QMessageBox.Yes: return True else: return False def saveFile(self): if self.editor.text() == '': return name = QFileDialog.getSaveFileName(self, 'Save File') print name if name[0]: file = open(name[0],'w') file.write(self.editor.text()) file.close() def emit_percent(self, percent): self.percentDone.emit(percent)
class PidgetStub(Pidget): def __init__(self, param, parent_instance): super().__init__(param, parent_instance) self.setObjectName("frame") self.default_css = "#frame {border: 1px solid lightgrey; border-radius: 3px;}" self.setStyleSheet(self.default_css) doc = param.generate_doc() if doc: doc = try_rst_to_html(doc) self.setToolTip(doc) self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 6, 0, 6) self.grid_widget = QWidget() self.layout.addWidget(self.grid_widget) self.grid = QGridLayout(self.grid_widget) self.grid.setContentsMargins(6, 0, 6, 0) self.alert_frame = QFrame() self.alert_frame.setStyleSheet( ".QFrame {border-top: 1px solid lightgrey;}") alert_layout = QHBoxLayout(self.alert_frame) alert_layout.setContentsMargins(6, 6, 6, 0) self.alert_label = QLabel() self.alert_label.setStyleSheet("color: #333333; font-weight: 600;") alert_layout.addWidget(self.alert_label) self.layout.addWidget(self.alert_frame) self._set_alert(None) def _update(self, alerts): state = self._parent_instance._state if state != cb.Config.State.UNLOADED: if callable(self.param.visible): visible = self.param.visible(self._parent_instance) else: visible = self.param.visible else: visible = False self.setVisible(bool(visible)) enabled = (state == cb.Config.State.LOADED or state == cb.Config.State.LIVE and self.param.is_live_updateable) self.setEnabled(enabled) self._set_alert(alerts) def _set_alert(self, alerts): if not alerts: self.alert_frame.hide() self.setStyleSheet(self.default_css) return if isinstance(alerts, cb.Alert): alert = alerts else: alerts = sorted(alerts, key=lambda a: a.severity) alert = alerts[0] if alert.severity == cb.Severity.ERROR: bg = "FFB9A8" elif alert.severity == cb.Severity.WARNING: bg = "FFDFA8" else: bg = "FFFFEE" self.setStyleSheet(("#frame {{" "background-color: #{};" "border: 1px solid lightgrey;" "border-radius: 3px;" "}}").format(bg)) self.alert_label.setText(alert.msg) self.alert_frame.show() def _subwidget_event_handler(self, val): try: super()._subwidget_event_handler(val) except ValueError: pass # TODO
class Dataset(QFrame): default_text = "<i>Please select a file.<\i>" download_text = "Download" downloading_text = "Downloading..." def __init__(self, app): super().__init__() # initialize our variables self.app = app self.file = None self.init_ui() def init_ui(self): # make our UI self.setObjectName("content") layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) # our main content area content = QFrame() content_layout = QVBoxLayout() # some info title = QLabel("Dataset") title.setObjectName("h1") description = QLabel( "Download images from URLs in a .csv or .xlsx file.\nOptionally, supply labels to organize your images into folders by label." ) description.setObjectName("h2") # file selection button self.file_button = QPushButton("Select file") self.file_button.clicked.connect(self.select_file) button_container = NoStretch(self.file_button) button_container.setObjectName("separate") # display filepath self.path_label = QLabel(self.default_text) # url column header and optional label column header self.header_container = QFrame() self.header_container.setObjectName("separateSmall") header_layout = QVBoxLayout() header_layout.setContentsMargins(0, 0, 0, 0) url_label = QLabel("Column with image URLs:") self.url_dropdown = QComboBox() self.url_dropdown.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.url_dropdown.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) url_container = NoStretch(self.url_dropdown) label_label = QLabel("(Optional) column with labels:") label_label.setObjectName("separateSmall") self.label_dropdown = QComboBox() self.label_dropdown.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.label_dropdown.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) label_container = NoStretch(self.label_dropdown) header_layout.addWidget(url_label) header_layout.addWidget(url_container) header_layout.addWidget(label_label) header_layout.addWidget(label_container) self.header_container.setLayout(header_layout) self.header_container.hide() # download button self.download_button = QPushButton(self.download_text) self.download_button.setEnabled(False) self.download_button.clicked.connect(self.download) download_container = NoStretch(self.download_button) download_container.setObjectName("separate") self.progress_bar = QProgressBar() self.progress_bar.hide() # make our content layout content_layout.addWidget(title) content_layout.addWidget(description) content_layout.addWidget(button_container) content_layout.addWidget(self.path_label) content_layout.addWidget(self.header_container) content_layout.addWidget(download_container) content_layout.addWidget(self.progress_bar) content_layout.addStretch(1) content.setLayout(content_layout) layout.addWidget(content) layout.addStretch(1) self.setLayout(layout) def select_file(self): self.file = QFileDialog.getOpenFileName(self, 'Select CSV File', filter="CSV (*.csv *.xlsx)")[0] self.path_label.setText( f"<i>{self.file}</i>" if self.file else self.default_text) self.parse_headers() def parse_headers(self): if self.file: # read the file for its headers and set our dropdown boxes appropriately try: if os.path.splitext(self.file)[1] == ".csv": csv = pd.read_csv(self.file, header=0) else: csv = pd.read_excel(self.file, header=0) self.label_dropdown.clear() self.url_dropdown.clear() self.label_dropdown.addItem(None) for header in list(csv.columns): self.url_dropdown.addItem(header) self.label_dropdown.addItem(header) self.url_dropdown.adjustSize() self.header_container.show() self.download_button.setEnabled(True) except Exception as e: QMessageBox.about(self, "Alert", f"Error reading csv: {e}") self.clear_headers() else: self.clear_headers() def clear_headers(self): self.header_container.hide() self.url_dropdown.clear() self.label_dropdown.clear() self.download_button.setEnabled(False) def download(self): # disable the buttons so we can't click again self.download_button.setEnabled(False) self.download_button.setText(self.downloading_text) self.file_button.setEnabled(False) self.progress_bar.setValue(0) self.progress_bar.show() self.app.processEvents() url_col = self.url_dropdown.currentText() label_col = self.label_dropdown.currentText() destination_directory = QFileDialog.getExistingDirectory( self, "Select Output Directory") # if they hit cancel, don't download if not destination_directory: self.done() return # otherwise try downloading to the desired location try: create_dataset( filepath=self.file, url_col=url_col, label_col=label_col if label_col else None, progress_hook=self.progress_hook, destination_directory=destination_directory, ) except Exception as e: QMessageBox.about(self, "Alert", f"Error creating dataset: {e}") self.done() def progress_hook(self, current, total): self.progress_bar.setValue(float(current) / total * 100) if current == total: self.done() # make sure to update the UI self.app.processEvents() def done(self): self.progress_bar.setValue(0) self.progress_bar.hide() self.download_button.setEnabled(True) self.download_button.setText(self.download_text) self.file_button.setEnabled(True) self.app.processEvents()