class Downloads(QWidget): def __init__(self): super(Downloads, self).__init__() self.history = get_download_history() self.history.reverse() self.layout = QStackedLayout() self.layout.setMargin(0) self.page_widget = QScrollArea() self.page_widget.setWidgetResizable(True) widget = QWidget(self.page_widget) widget.setMinimumWidth(350) self.page_widget.setWidget(widget) self.page_layout = QVBoxLayout(widget, alignment=Qt.AlignTop) self.page_layout.setMargin(0) self.page_layout.setContentsMargins(25, 25, 25, 25) self.layout.addWidget(self.page_widget) self.layout.setCurrentWidget(self.page_widget) if len(self.history) == 0: self.history_empty_label = QLabel('No downloads', alignment=Qt.AlignCenter) self.layout.addWidget(self.history_empty_label) self.layout.setCurrentWidget(self.history_empty_label) for item in self.history: self.page_layout.addWidget(DownloadItem(item=item)) self.setLayout(self.layout)
class MainWindowCentralWidget(QWidget): """ Container for all widgets of pages in the application. """ def __init__(self): QWidget.__init__(self) self.__MAIN_MENU_WIDGET_NAME = 'main_menu' self.__SETTINGS_WIDGET_NAME = 'settings' self.__FACE_LOAD_WIDGET_NAME = 'face load' self.__FACE_AUTH_WIDGET_NAME = 'face auth' self.__setup_ui() self.widgets = { self.__MAIN_MENU_WIDGET_NAME: self.main_menu_widget, self.__SETTINGS_WIDGET_NAME: self.settings_widget, self.__FACE_LOAD_WIDGET_NAME: self.face_loading_widget, self.__FACE_AUTH_WIDGET_NAME: self.face_authentication_widget } def __setup_ui(self): self.stacked_layout = QStackedLayout() self.main_menu_widget = MainMenuWidget(self) self.stacked_layout.addWidget(self.main_menu_widget) self.settings_widget = SettingsWidget(self) self.stacked_layout.addWidget(self.settings_widget) self.face_loading_widget = FaceLoadingWidget(self) self.stacked_layout.addWidget(self.face_loading_widget) self.face_authentication_widget = FaceAuthenticationWidget(self) self.stacked_layout.addWidget(self.face_authentication_widget) self.setLayout(self.stacked_layout) def set_current_widget(self, widget_name: str): """ Choose which widget (page) to display :param widget_name: name of the widget to switch """ self.stacked_layout.setCurrentWidget(self.widgets[widget_name]) def set_main_menu(self): self.set_current_widget(self.__MAIN_MENU_WIDGET_NAME) def open_face_load_widget(self): self.set_current_widget(self.__FACE_LOAD_WIDGET_NAME) def open_settings_widget(self): self.set_current_widget(self.__SETTINGS_WIDGET_NAME) def open_face_auth_widget(self): self.set_current_widget(self.__FACE_AUTH_WIDGET_NAME) @Slot() def change_widget(self): self.stacked_layout.setCurrentWidget(self.settings_widget)
class HomeFeed(QWidget): def __init__(self): super(HomeFeed, self).__init__() self.run_get_feed_thread() self.feed = [] self.page = 1 self.loading = False self.layout = QStackedLayout() self.layout.setMargin(0) self.loading_label = QLabel('Loading...', alignment=Qt.AlignCenter) self.layout.addWidget(self.loading_label) self.layout.setCurrentWidget(self.loading_label) self.page_widget = QScrollArea() self.page_widget.setWidgetResizable(True) self.page_widget.viewport().installEventFilter(self) widget = QWidget(self.page_widget) widget.setMinimumWidth(350) self.page_widget.setWidget(widget) self.flow_layout = FlowLayout(widget) self.flow_layout.setContentsMargins(25, 25, 25, 25) self.layout.addWidget(self.page_widget) self.setLayout(self.layout) def run_get_feed_thread(self): self.thread = RunThread(self.get_feed, self.on_feed_receive) def eventFilter(self, source, event): if (event.type() == QEvent.Wheel and source is self.page_widget.viewport() and not self.loading): scrollbar = self.page_widget.verticalScrollBar() y = scrollbar.value() bottom = scrollbar.maximum() if y >= bottom: self.page += 1 self.loading = True self.run_get_feed_thread() return super(HomeFeed, self).eventFilter(source, event) def get_feed(self): spider = CoreRadioSpider() self.feed = spider.get_home_feed(page=self.page) return True def on_feed_receive(self): if len(self.feed) > 0: for item in self.feed: preview_widget = SongPreview(artwork=item['artwork'], title=item['title'], url=item['href']) self.flow_layout.addWidget(preview_widget) self.loading = False self.layout.setCurrentWidget(self.page_widget) else: self.loading_label.setText( "Something wen't wrong, please try again")
class SongDetailPage(QWidget): def __init__(self, url=None): super(SongDetailPage, self).__init__() self.url = url self.loading = False self.artwork_content = None self.artwork_size = 400 self.song = None self.layout = QStackedLayout() self.layout.setMargin(0) self.loading_label = QLabel('Loading...', alignment=Qt.AlignCenter) self.layout.addWidget(self.loading_label) self.layout.setCurrentWidget(self.loading_label) self.page_widget = QScrollArea() self.page_widget.setWidgetResizable(True) widget = QWidget(self.page_widget) widget.setMinimumWidth(800) self.page_widget.setWidget(widget) self.page_layout = QVBoxLayout(widget, alignment=Qt.AlignTop) self.page_layout.setContentsMargins(25, 25, 25, 25) self.layout.addWidget(self.page_widget) self.setLayout(self.layout) self.thread = RunThread(self.get_song_info, self.on_song_info) def render_song_info(self): # Header self.page_layout.addWidget(Header(song=self.song)) # Title title = H2(self.song['title']) title.setWordWrap(True) title.setStyleSheet('padding-top: 20px;') self.page_layout.addWidget(title) # Inner container that contains Image + Songlist inner_container = QWidget() inner_container_layout = QHBoxLayout(alignment=Qt.AlignTop | Qt.AlignLeft) inner_container_layout.setMargin(0) inner_container_layout.setSpacing(25) inner_container_layout.setContentsMargins(0, 25, 0, 0) inner_container.setLayout(inner_container_layout) self.page_layout.addWidget(inner_container) # Image self.artwork_label = QLabel() self.artwork_label.setStyleSheet( css('background-color: {{color}};', color=colors.PLACEHOLDER_COLOR)) self.artwork_label.setFixedWidth(self.artwork_size) self.artwork_label.setFixedHeight(self.artwork_size) inner_container_layout.addWidget(self.artwork_label, alignment=Qt.AlignTop) self.get_artwork_thread = RunThread(self.fetch_artwork, self.on_artwork_loaded) # Songlist inner_container_layout.addWidget( Songlist(songlist=self.song['songlist']), alignment=Qt.AlignTop) def fetch_artwork(self): time.sleep(1) logging.info('GET {}'.format(self.song['artwork'])) try: response = requests.get(self.song['artwork']) self.artwork_content = response.content except Exception: return True return True def on_artwork_loaded(self): if self.artwork_content: imgWidget = QImage() imgWidget.loadFromData(self.artwork_content) picture = QPixmap(imgWidget) picture = picture.scaled(self.artwork_size, self.artwork_size, Qt.KeepAspectRatio) self.artwork_label.setPixmap(picture) else: logging.warn('[FAILED] GET {}'.format(self.song['artwork'])) def get_song_info(self): self.loading = True spider = CoreRadioSpider() self.song = spider.get_song_info(url=self.url) return True def on_song_info(self): if self.song is not None: self.render_song_info() self.loading = False self.layout.setCurrentWidget(self.page_widget) else: self.loading_label.setText( "Something wen't wrong, please try again")
class Sidebar(QWidget): def __init__(self, *args, **kwargs): super(Sidebar, self).__init__(*args, **kwargs) self.settings_scroll_area = QScrollArea() self.settings_scroll_area.setWidgetResizable(True) self.navigation = ImagesNav(parent=self) self.log = QTextEdit() self.log.setReadOnly(True) self.tabs = QTabWidget() self.tabs.addTab(self.navigation, "Images list") self.tabs.addTab(self.log, "Application log") self.layout = QStackedLayout() self.layout.addWidget(self.settings_scroll_area) self.layout.addWidget(self.tabs) self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.MinimumExpanding) self.setLayout(self.layout) self.layout.setCurrentWidget(self.tabs) def log_text(self, text, color="black"): time = datetime.datetime.now().time() if color == "red": self.log.setTextColor(QColor("red")) else: self.log.setTextColor(QColor("black")) self.log.append(f"{time}:\n {text}") main_window = self.parent().parent() main_window.statusBar().showMessage(text) self.log.setTextColor(QColor("grey")) self.log.append("--------------") def init_font_settings(self, text_item): font_layout = QVBoxLayout() font_layout.setAlignment(Qt.AlignTop) font_layout.addWidget(QLabel("Family")) font_layout.addWidget(init_font_families_widget(text_item)) font_layout.addWidget(QLabel("Size")) font_layout.addLayout(init_font_size_layout(text_item)) font_layout.addWidget(QLabel("Color")) font_layout.addWidget(init_font_color_widget(text_item)) font_layout.addWidget(QLabel("Style")) font_layout.addWidget(init_font_style_widget(text_item)) font_layout.addWidget(QLabel("Weight")) font_layout.addWidget(init_font_weight_widget(text_item)) font_layout.addWidget(QLabel("Capitalization")) font_layout.addWidget(init_capitalization_widget(text_item)) font_layout.addWidget(QLabel("Stretch")) font_layout.addWidget(init_stretch_layout(text_item)) font_layout.addWidget(init_kerning_widget(text_item)) font_layout.addWidget(init_overline_widget(text_item)) font_layout.addWidget(init_strikeout_widget(text_item)) font_layout.addWidget(init_underline_widget(text_item)) font_layout.addWidget(init_letter_spacing_widget(text_item)) font_group_box = QGroupBox("Font") font_group_box.setLayout(font_layout) layout = QVBoxLayout() layout.addWidget(font_group_box) text_item_group_box = QGroupBox("Text item") text_item_layout = QVBoxLayout() text_item_layout.setAlignment(Qt.AlignTop) text_item_layout.addLayout( init_item_opacity_layout(text_item)) text_item_layout.addLayout(init_item_rotation_layout(text_item)) text_item_group_box.setLayout(text_item_layout) layout.addWidget(text_item_group_box) layout.addWidget(self.init_item_duplicate_widget(text_item)) layout.addWidget(init_item_delete_widget(text_item)) settings = QWidget() settings.setLayout(layout) self.settings_scroll_area.setWidget(settings) self.layout.setCurrentWidget(self.settings_scroll_area) def init_image_settings(self, image_item): image_layout = QVBoxLayout() image_layout.setAlignment(Qt.AlignTop) image_group_box = QGroupBox("Image") image_layout.addLayout(init_item_opacity_layout(image_item)) image_layout.addSpacing(30) image_layout.addLayout(init_item_rotation_layout(image_item)) image_layout.addSpacing(30) image_layout.addLayout(init_image_scale_layout(image_item)) image_group_box.setLayout(image_layout) layout = QVBoxLayout() layout.addWidget(image_group_box) layout.addWidget(self.init_item_duplicate_widget(image_item)) layout.addWidget(init_item_delete_widget(image_item)) settings = QWidget() settings.setLayout(layout) self.settings_scroll_area.setWidget(settings) self.layout.setCurrentWidget(self.settings_scroll_area) def duplicate_item(self, item): item_config = item.get_config() if item_config["item_type"] == "text": new_item = custom_items.CustomQGraphicsTextItem() new_item.setParent(self) else: new_item = custom_items.CustomQGraphicsPixmapItem(item_config[ "image_path"]) new_item.parent = self new_item.path = item_config["image_path"] item.scene().addItem(new_item) new_item.load_config(item_config) new_item.scene().clearSelection() new_item.setSelected(True) def init_item_duplicate_widget(self, item): button = QPushButton("Duplicate") button.clicked.connect(lambda: self.duplicate_item(item)) return button