def setAlbumArt(self, imageData, deviceRatio): """Sets album art in song widget Args: imageData (bytes): A bytes literal containing embedded album art deviceRatio (int): Pixel ratio of the screen that this program runs on """ try: if imageData == b'' or imageData is None: albumImage = QtGui.QImage( utils.resource_path('./assets/art_empty.png')) else: albumImage = QtGui.QImage.fromData(imageData) if albumImage.isNull(): albumImage = QtGui.QImage( utils.resource_path('./assets/art_empty.png')) albumIcon = QtGui.QPixmap.fromImage(albumImage) albumIcon.setDevicePixelRatio(deviceRatio) self._iconWidth = deviceRatio * (self._albumArtLabel.width() - 10) self._iconHeight = deviceRatio * (self._albumArtLabel.height() - 10) self._albumArtLabel.setPixmap( albumIcon.scaled(self._iconWidth, self._iconHeight, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)) except: logger.log(logger.LOG_LEVEL_ERROR, 'Error setting album art.')
def write_to_file(log): with open(utils.resource_path('./modules/info.log'), 'r') as fin: data = fin.read().splitlines(False) with open(utils.resource_path('./modules/info.log'), 'w') as fout: cutoff = 1 if len(data) > 1000 else 0 data.append(log) string = '\n'.join(data[cutoff:]) fout.write(string)
def setIcon(self, url): icon = QtGui.QPixmap(utils.resource_path(url)) icon.setDevicePixelRatio(self.devicePixelRatio()) self._iconWidth = self.devicePixelRatio() * self._iconLabel.width() - 10 self._iconHeight = self.devicePixelRatio() * self._iconLabel.height() - 10 self._iconLabel.setPixmap(icon.scaled(self._iconWidth, self._iconHeight, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation))
def __init__(self, parent): super().__init__(parent) self._iconLabel = QtWidgets.QLabel() self._iconLabel.setFixedWidth(75) self._iconLabel.setFixedHeight(75) self._titleLabel = QtWidgets.QLabel() self._titleLabel.setFont(appearance.SMALL_FONT_BOLD) self._messageLabel = QtWidgets.QLabel() self._messageLabel.setFixedWidth(375) self._messageLabel.setMinimumHeight(self._messageLabel.minimumSizeHint().height()) self._messageLabel.setWordWrap(True) self._messageLabel.setFont(appearance.SMALLER_FONT) if utils.IS_MAC and utils.IS_MACOS_DARK_MODE: self._messageLabel.setStyleSheet('color: grey') else: self._messageLabel.setStyleSheet('color: dimgrey') # Option to suppress further errors self._showAgainCheckBox = QtWidgets.QCheckBox('Do not show this message again') self._showAgainCheckBox.stateChanged.connect(lambda state: self.showAgainAction(state)) self._showAgainCheckBox.setChecked(False) # Buttons self._noButton = QtWidgets.QPushButton('Cancel') self._noButton.setMaximumWidth(125) self._noButton.clicked.connect(self.noAction) self._showMoreButton = QtWidgets.QPushButton('Show Details') self._showMoreButton.setMaximumWidth(125) self._showMoreButton.clicked.connect(self.showDetails) self._okButton = QtWidgets.QPushButton('OK') self._okButton.setDefault(True) self._okButton.setMaximumWidth(125) self._okButton.clicked.connect(self.okAction) self._dialogGridLayout = QtWidgets.QGridLayout() # self._dialogGridLayout.setSpacing(0) self._dialogGridLayout.addWidget(self._iconLabel, 1, 0, 2, 1) self._dialogGridLayout.setAlignment(self._iconLabel, QtCore.Qt.AlignTop) self._dialogGridLayout.addWidget(self._titleLabel, 1, 1, 1, -1) self._dialogGridLayout.addWidget(self._messageLabel, 2, 1, 1, -1) self._dialogGridLayout.addWidget(self._showAgainCheckBox, 6, 1, 1, -1) self._dialogGridLayout.addWidget(self._showMoreButton, 7, 1, 1, 1) self._dialogGridLayout.addWidget(self._noButton, 7, 3, 1, 1) self._dialogGridLayout.addWidget(self._okButton, 7, 4, 1, 1) self.setLayout(self._dialogGridLayout) # Style error dialog if utils.IS_WINDOWS: self.setWindowIcon(QtGui.QIcon(utils.resource_path('./assets/icon.png'))) if not utils.IS_MAC: self.setWindowTitle('Quaver') self.setWindowModality(QtCore.Qt.ApplicationModal) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) flags = self.windowFlags() | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint flags &= ~(QtCore.Qt.WindowMinMaxButtonsHint | QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowFullscreenButtonHint) self.setWindowFlags(flags)
def playSuccessSound(self): # Playing sounded with PyQt causes this to happen when closing: # QCoreApplication::postEvent: Unexpected null receiver # I have no idea why and it doesn't seem to negatively affect UX # since it's closing anyway... if self._settings.play_sounds: QtMultimedia.QSound.play( utils.resource_path('./assets/success.wav'))
def setProgressIcon(self, state, deviceRatio): if state == states.IN_PROGRESS: imagePath = utils.resource_path('./assets/in_progress.png') elif state == states.ERROR: imagePath = utils.resource_path('./assets/error.png') elif state == states.COMPLETE: imagePath = utils.resource_path('./assets/complete.png') else: imagePath = utils.resource_path('./assets/not_started.png') self._state = state self._progressIcon = QtGui.QPixmap(imagePath) self._progressIcon.setDevicePixelRatio(deviceRatio) self._iconWidth = deviceRatio * self._progressLabel.width() self._iconHeight = deviceRatio * self._progressLabel.height() self._progressLabel.setPixmap( self._progressIcon.scaled(self._iconWidth, self._iconHeight, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation))
def __init__(self, parent=None): super().__init__(parent) # Style the window if utils.IS_WINDOWS: self.setWindowIcon( QtGui.QIcon(utils.resource_path('./assets/icon.png'))) # Get settings from settings.ini file self._settings = settings.Settings() # Wrapper for settings class def set_source(): self._settings.source = self._sourceComboBox.currentText() def set_approximate(state): self._settings.approximate = state def set_remove_brackets(state): self._settings.remove_brackets = state def set_info(state): self._settings.info = state def set_metadata(state): self._settings.metadata = state def set_text(state): self._settings.text = state def set_sounds(state): self._settings.play_sounds = state def set_errors(state): self._settings.show_errors = state def set_updates(state): self._settings.show_updates = state # Add settings controls self._sourceLabel = QtWidgets.QLabel('Lyrics source:') self._sourceLabel.setAlignment(QtCore.Qt.AlignRight) self._sourceComboBox = QtWidgets.QComboBox() self._sourceComboBox.setMaximumWidth(150) for source in utils.SUPPORTED_SOURCES: self._sourceComboBox.addItem(source) index = self._sourceComboBox.findText(self._settings.source, QtCore.Qt.MatchFixedString) self._sourceComboBox.currentIndexChanged.connect(set_source) if index >= 0: self._sourceComboBox.setCurrentIndex(index) self._optionsLabel = QtWidgets.QLabel('Lyrics options:') self._optionsLabel.setAlignment(QtCore.Qt.AlignRight) self._approximateCheckBox = QtWidgets.QCheckBox( 'Search only by song title and ignore artist') self._approximateCheckBox.setChecked(self._settings.approximate) self._approximateCheckBox.stateChanged.connect( lambda state: set_approximate(state)) self._bracketCheckBox = QtWidgets.QCheckBox( 'Remove parts of song title and artist in brackets\nwhen searching for lyrics' ) self._bracketCheckBox.setStyleSheet( 'QCheckBox::indicator { subcontrol-position: left top; }') self._bracketCheckBox.stateChanged.connect( lambda state: set_remove_brackets(state)) self._bracketCheckBox.setChecked(self._settings.remove_brackets) self._infoCheckBox = QtWidgets.QCheckBox( 'Add title and artist to top of saved lyrics') self._infoCheckBox.stateChanged.connect(lambda state: set_info(state)) self._infoCheckBox.setChecked(self._settings.info) self._metadataCheckBox = QtWidgets.QCheckBox( 'Save lyrics to song metadata\n(e.g. for display in music apps on phone)' ) self._metadataCheckBox.setStyleSheet( 'QCheckBox::indicator { subcontrol-position: left top; }') self._metadataCheckBox.stateChanged.connect( lambda state: set_metadata(state)) self._metadataCheckBox.setChecked(self._settings.metadata) self._textCheckBox = QtWidgets.QCheckBox('Save lyrics to a text file') self._textCheckBox.stateChanged.connect(lambda state: set_text(state)) self._textCheckBox.setChecked(self._settings.text) # Separator Line self._separatorLineFrame = QtWidgets.QFrame() self._separatorLineFrame.setFrameShape(QtWidgets.QFrame.HLine) self._separatorLineFrame.setFrameShadow(QtWidgets.QFrame.Raised) # Other controls self._playSoundsLabel = QtWidgets.QLabel('Sounds and dialogs:') self._playSoundsCheckBox = QtWidgets.QCheckBox('Enable sound effects') self._playSoundsCheckBox.stateChanged.connect( lambda state: set_sounds(state)) self._playSoundsCheckBox.setChecked(self._settings.play_sounds) self._showErrorCheckBox = QtWidgets.QCheckBox('Show error messages') self._showErrorCheckBox.stateChanged.connect( lambda state: set_errors(state)) self._showErrorCheckBox.setChecked(self._settings.show_errors) self._showUpdatesCheckBox = QtWidgets.QCheckBox('Show update messages') self._showUpdatesCheckBox.stateChanged.connect( lambda state: set_updates(state)) self._showUpdatesCheckBox.setChecked(self._settings.show_updates) # For testing # self._approximateCheckBox.setChecked(True) # self._tagCheckBox.setChecked(True) # Separator leave a bunch of space in case settings expands self._verticalSpacer = QtWidgets.QSpacerItem( 0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) # Add settings and about to dialog self._settingsGridLayout = QtWidgets.QGridLayout() self._settingsGridLayout.addWidget(self._sourceLabel, 0, 0) self._settingsGridLayout.addWidget(self._sourceComboBox, 0, 1) self._settingsGridLayout.addWidget(self._optionsLabel, 1, 0) self._settingsGridLayout.addWidget(self._approximateCheckBox, 1, 1) self._settingsGridLayout.addWidget(self._bracketCheckBox, 2, 1) self._settingsGridLayout.addWidget(self._infoCheckBox, 3, 1) self._settingsGridLayout.addWidget(self._metadataCheckBox, 4, 1) self._settingsGridLayout.addWidget(self._textCheckBox, 5, 1) self._settingsGridLayout.addWidget(self._separatorLineFrame, 6, 0, 1, -1) self._settingsGridLayout.addWidget(self._playSoundsLabel, 7, 0) self._settingsGridLayout.addWidget(self._playSoundsCheckBox, 7, 1) self._settingsGridLayout.addWidget(self._showErrorCheckBox, 8, 1) self._settingsGridLayout.addWidget(self._showUpdatesCheckBox, 9, 1) self._settingsGridLayout.addItem(self._verticalSpacer, 10, 0, -1, -1) self.setLayout(self._settingsGridLayout) # Style settings dialog if utils.IS_WINDOWS: self.setWindowIcon( QtGui.QIcon(utils.resource_path('./assets/icon.png'))) if utils.IS_MAC: self.setWindowTitle('Preferences') else: self.setWindowTitle('Settings') self.setWindowModality(QtCore.Qt.ApplicationModal) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setFixedSize(self.minimumSizeHint()) # Center dialog in relation to parent self.resize(self.minimumSizeHint()) self.move(parent.x() + (parent.width() - self.width()) / 2, parent.y() + (parent.height() - self.height()) / 2)
def playErrorSound(self): if self._settings.play_sounds: QtMultimedia.QSound.play(utils.resource_path('./assets/error.wav'))
def __init__(self): super(MainWindow, self).__init__() # Create a settings object self._settings = settings.Settings() # Create and add items to menubar # Actions are ordered by their location in the macOS menubar # macOS menubar is significantly larger by OS convention # See https://developer.apple.com/design/human-interface-guidelines/macos/menus/menu-bar-menus/ self._openAboutAction = QtWidgets.QAction('About Quaver') self._openAboutAction.triggered.connect(self.openAboutDialog) if utils.IS_MAC: self._openSettingsAction = QtWidgets.QAction('Preferences') else: self._openSettingsAction = QtWidgets.QAction('Settings') self._openSettingsAction.setShortcut('Ctrl+Comma') self._openSettingsAction.triggered.connect(self.openSettingsDialog) self._openFileAction = QtWidgets.QAction('Open File...', self) self._openFileAction.setShortcut('Ctrl+O') self._openFileAction.triggered.connect( lambda: self.openFileDialog(QtWidgets.QFileDialog.ExistingFiles)) self._openFolderAction = QtWidgets.QAction('Open Folder...', self) self._openFolderAction.setShortcut('Ctrl+Shift+O') self._openFolderAction.triggered.connect( lambda: self.openFileDialog(QtWidgets.QFileDialog.Directory)) self._closeAction = QtWidgets.QAction('Close') self._closeAction.setShortcut('Ctrl+W') self._closeAction.triggered.connect(self.close) if utils.IS_MAC: self._openFinderAction = QtWidgets.QAction( 'Open Selected File in Finder', self) self._openFinderAction.triggered.connect(self.openFinder) self._openFinderAction.setEnabled(False) self._removeAllAction = QtWidgets.QAction('Remove All Files') self._removeAllAction.setShortcut('Ctrl+Shift+Backspace') self._removeAllAction.triggered.connect(self.removeAllFilesFromList) self._removeCompletedAction = QtWidgets.QAction( 'Remove All Files with Lyrics') self._removeCompletedAction.setShortcut('Ctrl+Alt+Shift+Backspace') self._removeCompletedAction.triggered.connect( self.removeCompletedFiles) self._removeCurrentAction = QtWidgets.QAction('Remove Selected File') self._removeCurrentAction.setShortcut('Ctrl+Backspace') self._removeCurrentAction.triggered.connect(self.removeCurrentFile) self._removeCurrentAction.setEnabled(False) if utils.IS_MAC: self._copyLyricsAction = QtWidgets.QAction('Copy Lyrics') self._copyLyricsAction.setShortcut('Ctrl+C') self._copyLyricsAction.triggered.connect(self.copyLyrics) self._copyLyricsAction.setEnabled(False) self._saveLyricsAction = QtWidgets.QAction('Save Lyrics') self._saveLyricsAction.setShortcut('Ctrl+S') self._saveLyricsAction.triggered.connect(self.saveLyrics) self._saveLyricsAction.setEnabled(False) self._removeLyricsAction = QtWidgets.QAction('Remove Lyrics') self._removeLyricsAction.setShortcut('Ctrl+Shift+X') self._removeLyricsAction.triggered.connect(self.removeLyrics) self._removeLyricsAction.setEnabled(False) self._undoAction = QtWidgets.QAction('Undo Typing') self._undoAction.setShortcut('Ctrl+Z') self._undoAction.triggered.connect(self.undoLyrics) self._undoAction.setEnabled(False) self._redoAction = QtWidgets.QAction('Redo Typing') self._redoAction.setShortcut('Ctrl+Shift+Z') self._redoAction.triggered.connect(self.redoLyrics) self._redoAction.setEnabled(False) self._viewSongsSubMenuAction = QtWidgets.QAction( 'View Lyrics For...', self) self._noLyricsAction = QtWidgets.QAction('No songs added', self) self._noLyricsAction.setEnabled(False) self._viewPreviousAction = QtWidgets.QAction('View Previous', self) self._viewPreviousAction.setShortcut('Ctrl+Up') self._viewPreviousAction.triggered.connect(self.viewPreviousWidget) self._viewPreviousAction.setEnabled(False) self._viewNextAction = QtWidgets.QAction('View Next', self) self._viewNextAction.setShortcut('Ctrl+Down') self._viewNextAction.triggered.connect(self.viewNextWidget) self._viewNextAction.setEnabled(False) self._toolBarAction = QtWidgets.QAction('Hide Toolbar', self) self._toolBarAction.setShortcut('Ctrl+Alt+T') self._toolBarAction.triggered.connect(self.toggleToolBar) self._minimizeAction = QtWidgets.QAction('Minimize', self) self._minimizeAction.setShortcut('Ctrl+M') self._minimizeAction.triggered.connect(self.toggleMinimized) self._maximizeAction = QtWidgets.QAction('Zoom', self) self._maximizeAction.triggered.connect(self.toggleMaximized) self._showNormalAction = QtWidgets.QAction('Bring to Front', self) self._showNormalAction.triggered.connect(self.showNormal) self._helpAction = QtWidgets.QAction('Help', self) self._helpAction.triggered.connect(self.openAboutDialog) if utils.IS_MAC: self._menuBar = QtWidgets.QMenuBar() else: self._menuBar = self.menuBar() if utils.IS_MAC: self._fileMenu = self._menuBar.addMenu('Quaver') self._fileMenu.addAction(self._openAboutAction) self._fileMenu.addSeparator() self._fileMenu.addAction(self._openSettingsAction) self._fileMenu = self._menuBar.addMenu('File') self._fileMenu.addAction(self._openFileAction) self._fileMenu.addAction(self._openFolderAction) if utils.IS_MAC: self._fileMenu.addSeparator() self._fileMenu.addAction(self._openFinderAction) self._fileMenu.addSeparator() self._fileMenu.addAction(self._closeAction) self._editMenu = self._menuBar.addMenu('Edit') self._editMenu.addAction(self._removeCurrentAction) self._editMenu.addSeparator() self._editMenu.addAction(self._removeAllAction) self._editMenu.addAction(self._removeCompletedAction) if utils.IS_MAC: self._editMenu.addSeparator() self._editMenu.addAction(self._copyLyricsAction) self._editMenu.addAction(self._saveLyricsAction) self._editMenu.addAction(self._removeLyricsAction) self._editMenu.addAction(self._undoAction) self._editMenu.addAction(self._redoAction) self._viewMenu = self._menuBar.addMenu('View') self._viewMenu.addAction(self._viewSongsSubMenuAction) self._songsSubMenu = QtWidgets.QMenu(self._menuBar) self._songsSubMenu.addAction(self._noLyricsAction) self._viewSongsSubMenuAction.setMenu(self._songsSubMenu) self._viewMenu.addSeparator() self._viewMenu.addAction(self._viewPreviousAction) self._viewMenu.addAction(self._viewNextAction) self._viewMenu.addSeparator() self._viewMenu.addAction(self._toolBarAction) self._windowMenu = self._menuBar.addMenu('Window') self._windowMenu.addAction(self._minimizeAction) self._windowMenu.addAction(self._maximizeAction) self._windowMenu.addSeparator() self._windowMenu.addAction(self._showNormalAction) if not utils.IS_MAC: self._toolsMenu = self._menuBar.addMenu('Tools') self._toolsMenu.addAction(self._openSettingsAction) self._helpMenu = self._menuBar.addMenu('Help') self._helpMenu.addAction(self._helpAction) if not utils.IS_MAC: self._helpMenu.addAction(self._openAboutAction) # Create toolbar, but only on Mac # On other platforms, the menubar essentially takes on the role that the menu bar takes on Mac if utils.IS_MAC: self._leftAlignSpacer = QtWidgets.QSpacerItem( 15, 25, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) if utils.IS_MACOS_DARK_MODE: self._addFileButton = QtWidgets.QPushButton( QtGui.QIcon( utils.resource_path( './assets/add_music_inverted.png')), 'Add song') self._addFolderButton = QtWidgets.QPushButton( QtGui.QIcon( utils.resource_path( './assets/add_folder_inverted.png')), 'Add folder') self._removeFileButton = QtWidgets.QPushButton( QtGui.QIcon( utils.resource_path('./assets/delete_inverted.png')), 'Remove all') self._settingsButton = QtWidgets.QPushButton( QtGui.QIcon( utils.resource_path('./assets/settings_inverted.png')), 'Preferences') else: self._addFileButton = QtWidgets.QPushButton( QtGui.QIcon(utils.resource_path('./assets/add_music.png')), 'Add song') self._addFileButton.pressed.connect( lambda: self._addFileButton.setIcon( QtGui.QIcon( utils.resource_path( './assets/add_music_inverted.png')))) self._addFileButton.released.connect( lambda: self._addFileButton.setIcon( QtGui.QIcon( utils.resource_path('./assets/add_music.png')))) self._addFolderButton = QtWidgets.QPushButton( QtGui.QIcon( utils.resource_path('./assets/add_folder.png')), 'Add folder') self._addFolderButton.pressed.connect( lambda: self._addFolderButton.setIcon( QtGui.QIcon( utils.resource_path( './assets/add_folder_inverted.png')))) self._addFolderButton.released.connect( lambda: self._addFolderButton.setIcon( QtGui.QIcon( utils.resource_path('./assets/add_folder.png')))) self._removeFileButton = QtWidgets.QPushButton( QtGui.QIcon(utils.resource_path('./assets/delete.png')), 'Remove all') self._removeFileButton.pressed.connect( lambda: self._removeFileButton.setIcon( QtGui.QIcon( utils.resource_path('./assets/delete_inverted.png') ))) self._removeFileButton.released.connect( lambda: self._removeFileButton.setIcon( QtGui.QIcon(utils.resource_path('./assets/delete.png')) )) self._settingsButton = QtWidgets.QPushButton( QtGui.QIcon(utils.resource_path('./assets/settings.png')), 'Preferences') self._settingsButton.pressed.connect( lambda: self._settingsButton.setIcon( QtGui.QIcon( utils.resource_path( './assets/settings_inverted.png')))) self._settingsButton.released.connect( lambda: self._settingsButton.setIcon( QtGui.QIcon( utils.resource_path('./assets/settings.png')))) self._addFileButton.clicked.connect(lambda: self.openFileDialog( QtWidgets.QFileDialog.ExistingFiles)) self._addFolderButton.clicked.connect( lambda: self.openFileDialog(QtWidgets.QFileDialog.Directory)) self._removeFileButton.clicked.connect(self.removeAllFilesFromList) self._horizontalSpacer = QtWidgets.QSpacerItem( 20, 25, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self._settingsButton.clicked.connect(self.openSettingsDialog) self._rightAlignSpacer = QtWidgets.QSpacerItem( 15, 25, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) self._toolBarLayout = QtWidgets.QHBoxLayout() self._toolBarLayout.addItem(self._leftAlignSpacer) self._toolBarLayout.addWidget(self._addFileButton) self._toolBarLayout.addWidget(self._addFolderButton) self._toolBarLayout.addWidget(self._removeFileButton) self._toolBarLayout.addItem(self._horizontalSpacer) self._toolBarLayout.addWidget(self._settingsButton) self._toolBarLayout.addItem(self._rightAlignSpacer) self._toolBarLayout.setSpacing(5) self._toolBarLayout.setContentsMargins(0, 0, 0, 0) self._toolBarItems = QtWidgets.QWidget() self._toolBarItems.setLayout(self._toolBarLayout) # Add toolbar to window with name 'main' self._toolBar = self.addToolBar('main') self._toolBar.addWidget(self._toolBarItems) self._toolBar.setFloatable(False) self._toolBar.setMovable(False) self._toolBarVisible = True if utils.IS_MACOS_DARK_MODE: # Workaround for the weird white line that shows up at the bottom. self._toolBar.setStyleSheet('\ QToolBar {border-bottom: 1px solid rgb(21, 24, 24); \ border-top: 0px; \ background-color: rgb(42, 42, 42)}') self.setContextMenuPolicy(QtCore.Qt.NoContextMenu) # Create a hint for the user # This is the image/text in middle of screen on startup self._instructionIconLabel = QtWidgets.QLabel() self._instructionIconLabel.setSizePolicy( QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self._instructionIconLabel.setAlignment(QtCore.Qt.AlignCenter) self._quaverIcon = QtGui.QPixmap( utils.resource_path('./assets/icon_monochrome.png')) self._quaverIcon.setDevicePixelRatio(self.devicePixelRatio()) self._iconWidth = self.devicePixelRatio() * 150 self._iconHeight = self.devicePixelRatio() * 150 self._instructionIconLabel.setPixmap( self._quaverIcon.scaled(self._iconWidth, self._iconHeight, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)) self._verticalSpacer = QtWidgets.QSpacerItem( 20, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) if utils.IS_MAC: self._instructionLabel = QtWidgets.QLabel( 'Grab lyrics by adding a song.' '<br>Drag a song in, or click "Add song" to get started.') else: self._instructionLabel = QtWidgets.QLabel( 'Grab lyrics by adding a song.' '<br>Drag a song in, or open the "File" menu to get started.') self._instructionLabel.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self._instructionLabel.setAlignment(QtCore.Qt.AlignCenter) self._instructionLabel.setStyleSheet('color: grey') self._instructionLabel.setFont(appearance.SMALL_FONT) self._removedInstructions = False # This layout contains all the items in the song list # Style the layout: spacing (between items), content (padding within items) self._mainScrollAreaWidgetLayout = QtWidgets.QVBoxLayout() self._mainScrollAreaWidgetLayout.setAlignment(QtCore.Qt.AlignCenter) self._mainScrollAreaWidgetLayout.setSpacing(0) self._mainScrollAreaWidgetLayout.setContentsMargins(0, 0, 0, 0) self._mainScrollAreaWidgetLayout.addWidget(self._instructionIconLabel) self._mainScrollAreaWidgetLayout.addItem(self._verticalSpacer) self._mainScrollAreaWidgetLayout.addWidget(self._instructionLabel) # mainScrollAreaWidget contains the layout that contains all listwidgets self._mainScrollAreaWidget = QtWidgets.QWidget() self._mainScrollAreaWidget.setMinimumWidth(400) self._mainScrollAreaWidget.setLayout(self._mainScrollAreaWidgetLayout) # Create QScrollArea to contains widget containing list of all list items # NOTE: Not using QListWidget because scrolling is choppy on macOS self._mainScrollArea = QtWidgets.QScrollArea(self) self._mainScrollArea.setFrameShape(QtWidgets.QFrame.NoFrame) self._mainScrollArea.setWidgetResizable(True) self._mainScrollArea.setAttribute(QtCore.Qt.WA_MacShowFocusRect, False) self._mainScrollArea.setFocusPolicy(QtCore.Qt.NoFocus) self._mainScrollArea.setWidget(self._mainScrollAreaWidget) self.setCentralWidget(self._mainScrollArea) # Style main window self.setMinimumSize(600, 400) self.setUnifiedTitleAndToolBarOnMac(True) if not utils.IS_MAC: self.setWindowIcon( QtGui.QIcon(utils.resource_path('./assets/icon.png'))) self.setAcceptDrops(True)
def __init__(self, parent): super().__init__(parent) self.parent = parent # Add label for progress icon self._progressLabel = QtWidgets.QLabel() self._progressLabel.setFixedWidth(15) self._progressLabel.setAlignment(QtCore.Qt.AlignCenter) # Add album art label self._albumArtLabel = QtWidgets.QLabel() self._albumArtLabel.setFixedWidth(80) self._albumArtLabel.setFixedHeight(80) self._albumArtLabel.setMargin(0) # Add title and artist text labels self._textTitleLabel = QtWidgets.QLabel() self._textTitleLabel.setFont(appearance.MEDIUM_FONT) self._textArtistLabel = QtWidgets.QLabel() self._textArtistLabel.setFont(appearance.SMALL_FONT) if utils.IS_WINDOWS: self._textArtistLabel.setStyleSheet('color: dimgrey') self._textVBoxLayout = QtWidgets.QVBoxLayout() self._textVBoxLayout.addWidget(self._textTitleLabel) self._textVBoxLayout.addWidget(self._textArtistLabel) self._textVBoxLayout.setSpacing(0) # For testing purposes # self._textTitleQLabel.setStyleSheet(''' # background: rgb(0, 0, 255); # ''') # self._textArtistQLabel.setStyleSheet(''' # background: rgb(255, 0, 0); # ''') # Add buttons self._lyricsButton = QtWidgets.QPushButton( QtGui.QIcon(utils.resource_path('./assets/lyrics.png')), 'View Lyrics') self._lyricsButton.setFocusPolicy(QtCore.Qt.NoFocus) if utils.IS_MAC and not utils.IS_MACOS_DARK_MODE: self._lyricsButton.pressed.connect( lambda: self._lyricsButton.setIcon( QtGui.QIcon( utils.resource_path('./assets/lyrics_inverted.png')))) self._lyricsButton.released.connect( lambda: self._lyricsButton.setIcon( QtGui.QIcon(utils.resource_path('./assets/lyrics.png')))) elif utils.IS_MACOS_DARK_MODE: self._lyricsButton.setIcon( QtGui.QIcon( utils.resource_path('./assets/lyrics_inverted.png'))) self._lyricsButton.clicked.connect(lambda: self.openDetailDialog()) if utils.IS_MAC: self._openButton = QtWidgets.QPushButton('Open in Finder') elif utils.IS_WINDOWS: self._openButton = QtWidgets.QPushButton('Open in Explorer') else: self._openButton = QtWidgets.QPushButton('Open in File Browser') self._openButton.setFocusPolicy(QtCore.Qt.NoFocus) if utils.IS_WINDOWS: self._openButton.setFixedWidth( self._lyricsButton.minimumSizeHint().width() + 50) self._lyricsButton.setFixedWidth( self._lyricsButton.minimumSizeHint().width() + 50) else: self._openButton.setFixedWidth(self._openButton.sizeHint().width()) self._lyricsButton.setFixedWidth( self._openButton.sizeHint().width()) self._openButton.clicked.connect(lambda: self.openFilepath()) # self._removeButton = QtWidgets.QPushButton('Remove') # self._removeButton.setMaximumWidth(125) # self._removeButton.clicked.connect(lambda: self.removeFromList()) self._buttonVBoxLayout = QtWidgets.QVBoxLayout() self._buttonVBoxLayout.addWidget(self._lyricsButton) self._buttonVBoxLayout.addWidget(self._openButton) # self._buttonVBoxLayout.addWidget(self._removeButton) self._buttonVBoxLayout.setSpacing(0) # Layout containing all elements self._allHBoxLayout = QtWidgets.QHBoxLayout() if utils.IS_WINDOWS: self._leftSpacer = QtWidgets.QSpacerItem( 5, 25, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) self._allHBoxLayout.addItem(self._leftSpacer) self._allHBoxLayout.addWidget(self._progressLabel, 0) self._allHBoxLayout.addWidget(self._albumArtLabel, 1) self._allHBoxLayout.addLayout(self._textVBoxLayout, 2) self._allHBoxLayout.addLayout(self._buttonVBoxLayout, 3) if utils.IS_WINDOWS: self._rightSpacer = QtWidgets.QSpacerItem( 10, 25, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) self._allHBoxLayout.addItem(self._rightSpacer) self.setLayout(self._allHBoxLayout) self.setFocusPolicy(QtCore.Qt.NoFocus) # Initialize various parameters to nothing self._artist = '' self._title = '' self._lyrics = '' self._url = ''
def __init__(self, parent=None): super().__init__(parent) self._parent = parent # Metadata about Quaver self._iconLabel = QtWidgets.QLabel() self._iconLabel.setFixedWidth(100) self._iconLabel.setFixedHeight(100) self._aboutIcon = QtGui.QPixmap( utils.resource_path('./assets/icon.png')) self._aboutIcon.setDevicePixelRatio(self.devicePixelRatio()) self._iconWidth = self.devicePixelRatio() * self._iconLabel.width() self._iconHeight = self.devicePixelRatio() * self._iconLabel.height() self._iconLabel.setPixmap( self._aboutIcon.scaled(self._iconWidth, self._iconHeight, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)) self._nameLabel = QtWidgets.QLabel('Quaver') self._nameLabel.setFont(appearance.LARGE_FONT) self._sloganLabel = QtWidgets.QLabel('Quickly find your lyrics') self._sloganLabel.setFont(appearance.SMALL_FONT) # Spacer as separator self._verticalSpacer = QtWidgets.QSpacerItem( 50, 50, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) # Buttons # self._projectLinkButton = QtWidgets.QPushButton('See on Github...') self._checkUpdatesButton = QtWidgets.QPushButton('Check for updates') self._checkUpdatesButton.setFocusPolicy(QtCore.Qt.NoFocus) self._checkUpdatesButton.clicked.connect( lambda: self.check_for_updates()) # Credits if utils.IS_MAC and utils.IS_MACOS_DARK_MODE: self._creditsLabel = QtWidgets.QLabel(( '<center>Made with love for the community' '<br>Check it out on <a href=https://github.com/ns3098/lyrics-grabber style="color: white; text-decoration: none">Github</a>!</center>' )) self._iconsCreditsLabel = QtWidgets.QLabel(( '<center>UI icons from <a href=https://feathericons.com style="color: white; text-decoration: none">Feather Icons</a>' '<br>Quaver icon based on <a href=https://commons.wikimedia.org/wiki/File:Eighth_rest.svg style="color: white; text-decoration: none">Marmelad</a>' '<br>Warning icon from <a href=https://openclipart.org/detail/29833/warning-icon style="color: white; text-decoration: none">matthewgarysmith</a>' '<br>Download icon from <a href=https://openclipart.org/detail/218662/download-icon style="color: white; text-decoration: none">qubodup</a>' '<br>Sounds contributed by <a href=https://sonniss.com style="color: white; text-decoration: none">Sonniss</a>' '<br><br>Built with <a href=https://www.python.org style="color: white; text-decoration: none">Python</a>' ' and <a href=https://riverbankcomputing.com/software/pyqt/intro style="color: white; text-decoration: none">PyQt</a></center>' )) else: self._creditsLabel = QtWidgets.QLabel(( '<center>Made with love for the community' '<br>Check it out on <a href=https://github.com/ns3098/lyrics-grabber>Github</a>!</center>' )) self._iconsCreditsLabel = QtWidgets.QLabel(( '<center>UI icons from <a href=https://feathericons.com style="color: black; text-decoration: none">Feather Icons</a>' '<br>Quaver icon based on <a href=https://commons.wikimedia.org/wiki/File:Eighth_rest.svg style="color: black; text-decoration: none">Marmelad</a>' '<br>Warning icon from <a href=https://openclipart.org/detail/29833/warning-icon style="color: black; text-decoration: none">matthewgarysmith</a>' '<br>Download icon from <a href=https://openclipart.org/detail/218662/download-icon style="color: black; text-decoration: none">qubodup</a>' '<br>Sounds contributed by <a href=https://sonniss.com style="color: black; text-decoration: none">Sonniss</a>' '<br><br>Built with <a href=https://www.python.org style="color: black; text-decoration: none">Python</a>' ' and <a href=https://riverbankcomputing.com/software/pyqt/intro style="color: black; text-decoration: none">PyQt</a></center>' )) self._creditsLabel.setOpenExternalLinks(True) self._iconsCreditsLabel.setOpenExternalLinks(True) self._iconsCreditsLabel.setFont(appearance.TINY_FONT) self._versionLabel = QtWidgets.QLabel('Build {}-{}'.format( utils.VERSION_NUMBER, utils.CHANNEL)) self._versionLabel.setFont(appearance.TINY_FONT) # self._pal = QtGui.QPalette() # self._pal.setColor(QtGui.QPalette.Background, QtCore.Qt.white) # self._iconLabel.setAutoFillBackground(True) # self._iconLabel.setPalette(self._pal) self._aboutGridLayout = QtWidgets.QGridLayout() if utils.IS_WINDOWS: self._aboutGridLayout.setVerticalSpacing(15) self._aboutGridLayout.addWidget(self._iconLabel, 0, 0, 1, -1, QtCore.Qt.AlignCenter) self._aboutGridLayout.addWidget(self._nameLabel, 1, 0, 1, -1, QtCore.Qt.AlignCenter) self._aboutGridLayout.addWidget(self._sloganLabel, 2, 0, 1, -1, QtCore.Qt.AlignCenter) # self._aboutGridLayout.addWidget(self._projectLinkButton, 3, 0, 1, 1, QtCore.Qt.AlignCenter) self._aboutGridLayout.addWidget(self._checkUpdatesButton, 3, 0, 1, 1, QtCore.Qt.AlignCenter) # self._aboutGridLayout.addItem(self._verticalSpacer, 4, 0, 2, 1, QtCore.Qt.AlignCenter) self._aboutGridLayout.addWidget(self._creditsLabel, 4, 0, 1, -1, QtCore.Qt.AlignCenter) self._aboutGridLayout.addWidget(self._iconsCreditsLabel, 5, 0, 1, -1, QtCore.Qt.AlignCenter) self._aboutGridLayout.addWidget(self._versionLabel, 9, 0, 1, -1, QtCore.Qt.AlignCenter) self.setLayout(self._aboutGridLayout) # Style about dialog if utils.IS_WINDOWS: self.setWindowIcon( QtGui.QIcon(utils.resource_path('./assets/icon.png'))) self.setWindowTitle('About Quaver') self.setWindowModality(QtCore.Qt.ApplicationModal) if not utils.IS_WINDOWS: self.setFixedSize(self.minimumSizeHint()) else: self.setFixedSize(200, self.minimumSizeHint().height()) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) # Center dialog in relation to parent self.resize(self.minimumSizeHint()) self.move(parent.x() + (parent.width() - self.width()) / 2, parent.y() + (parent.height() - self.height()) / 2)