1
0
Fork 0
mirror of synced 2024-06-24 01:00:43 +12:00

Nice look of search results; better look for shop info; added ImageLabel in extra_widgets.py

This commit is contained in:
Dummerle 2021-06-10 14:13:28 +02:00
parent 9d02187d2f
commit 337b738599
6 changed files with 120 additions and 71 deletions

View file

@ -1,33 +1,43 @@
from PyQt5 import QtGui
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QScrollArea, QGroupBox
from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QScrollArea, QGroupBox, QPushButton
from rare.utils.extra_widgets import ImageLabel, FlowLayout
class SearchResults(QScrollArea):
class SearchResults(QWidget):
show_info = pyqtSignal(dict)
# TODO nice look
def __init__(self):
super(SearchResults, self).__init__()
self.main_layout = QVBoxLayout()
self.back_button = QPushButton()
self.main_layout.addWidget(self.back_button)
self.main_layout.addWidget(self.back_button)
self.result_area = QScrollArea()
self.widget = QWidget()
self.layout = QVBoxLayout()
self.result_area.setWidgetResizable(True)
self.main_layout.addWidget(self.result_area)
self.result_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.result_area.setWidget(self.widget)
self.layout = FlowLayout()
self.widget.setLayout(self.layout)
self.setWidget(self.widget)
self.setWidgetResizable(True)
self.setLayout(self.main_layout)
def show_results(self, results: list):
QVBoxLayout().addWidget(self.widget)
self.widget = QWidget()
self.layout = QVBoxLayout()
for i in range(self.layout.count()):
self.layout.removeItem(i)
self.layout = FlowLayout()
for res in results:
w = _SearchResultItem(res)
w.show_info.connect(self.show_info.emit)
self.layout.addWidget(w)
self.layout.addStretch(1)
self.widget.setLayout(self.layout)
self.setWidget(self.widget)
self.result_area.setWidget(self.widget)
class _SearchResultItem(QGroupBox):
@ -36,17 +46,41 @@ class _SearchResultItem(QGroupBox):
def __init__(self, result: dict):
super(_SearchResultItem, self).__init__()
self.layout = QHBoxLayout()
self.layout = QVBoxLayout()
self.image = ImageLabel()
for img in result["keyImages"]:
if img["type"] == "DieselStoreFrontTall":
width = 240
self.image.update_image(img["url"], result["title"], (width, 360))
break
else:
print("No image found")
self.layout.addWidget(self.image)
self.res = result
self.title = QLabel(self.res["title"])
title_font = QFont()
title_font.setPixelSize(15)
self.title.setFont(title_font)
self.title.setWordWrap(True)
self.layout.addWidget(self.title)
original_price = result['price']['totalPrice']['fmtPrice']['originalPrice']
self.price = QLabel(f"{self.tr('Original price: ')}{original_price}")
self.layout.addWidget(self.price)
price = result['price']['totalPrice']['fmtPrice']['originalPrice']
discount_price = result['price']['totalPrice']['fmtPrice']['discountPrice']
price_layout = QHBoxLayout()
price = QLabel(price)
price_layout.addWidget(price)
if price != discount_price:
font = QFont()
font.setStrikeOut(True)
price.setFont(font)
price_layout.addWidget(QLabel(discount_price))
# self.discount_price = QLabel(f"{self.tr('Discount price: ')}{discount_price}")
self.layout.addLayout(price_layout)
self.setLayout(self.layout)
self.setFixedWidth(260)
def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None:
if a0.button() == 1:
self.show_info.emit(self.res)

View file

@ -2,16 +2,15 @@ import json
import logging
import webbrowser
from PyQt5.QtCore import QLocale, QUrl, QJsonDocument, QJsonParseError, Qt
from PyQt5.QtCore import QUrl, QJsonDocument, QJsonParseError
from PyQt5.QtGui import QPixmap, QFont
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
from PyQt5.QtWidgets import QWidget, QLabel
from rare.utils.utils import get_lang
from rare.utils.extra_widgets import WaitingSpinner
from rare.components.tabs.shop.shop_models import ShopGame
from rare.ui.components.tabs.store.shop_game_info import Ui_shop_info
from rare.utils.extra_widgets import WaitingSpinner, ImageLabel
from rare.utils.utils import get_lang
logger = logging.getLogger("ShopInfo")
@ -25,6 +24,8 @@ class ShopGameInfo(QWidget, Ui_shop_info):
super(ShopGameInfo, self).__init__()
self.setupUi(self)
self.open_store_button.clicked.connect(self.button_clicked)
self.image = ImageLabel()
self.image_stack.addWidget(self.image)
self.image_stack.addWidget(WaitingSpinner())
self.manager = QNetworkAccessManager()
@ -48,7 +49,6 @@ class ShopGameInfo(QWidget, Ui_shop_info):
# init API request
locale = get_lang()
locale = "en"
url = f"https://store-content.ak.epicgames.com/api/{locale}/content/{'products' if not is_bundle else 'bundles'}/{slug}"
# game = api_utils.get_product(slug, locale)
self.request = self.manager.get(QNetworkRequest(QUrl(url)))
@ -76,7 +76,11 @@ class ShopGameInfo(QWidget, Ui_shop_info):
self.title.setText(self.game.title)
self.price.setText(self.game.price)
self.discount_price.setText(self.game.discount_price)
if self.game.price != self.game.discount_price:
self.discount_price.setText(self.game.discount_price)
self.discount_price.setVisible(True)
else:
self.discount_price.setVisible(False)
# print(self.game.reqs)
bold_font = QFont()
bold_font.setBold(True)
@ -88,16 +92,19 @@ class ShopGameInfo(QWidget, Ui_shop_info):
self.req_group_box.layout().addWidget(rec_label, 0, 2)
for i, (key, value) in enumerate(self.game.reqs["Windows"].items()):
self.req_group_box.layout().addWidget(QLabel(key), i+1, 0)
self.req_group_box.layout().addWidget(QLabel(key), i + 1, 0)
min_label = QLabel(value[0])
min_label.setWordWrap(True)
self.req_group_box.layout().addWidget(min_label, i+1, 1)
self.req_group_box.layout().addWidget(min_label, i + 1, 1)
rec_label = QLabel(value[1])
rec_label.setWordWrap(True)
self.req_group_box.layout().addWidget(rec_label, i+1, 2)
self.req_group_box.layout().addWidget(rec_label, i + 1, 2)
self.image_request = self.manager.get(QNetworkRequest(QUrl(self.game.image_urls.offer_image_tall)))
self.image_request.finished.connect(self.image_loaded)
self.image.update_image(self.game.image_urls.front_tall, self.game.title, (240, 320))
self.image_stack.setCurrentIndex(0)
# self.image_request = self.manager.get(QNetworkRequest(QUrl(self.game.image_urls.offer_image_tall)))
# self.image_request.finished.connect(self.image_loaded)
try:
if isinstance(self.game.developer, list):
@ -111,16 +118,5 @@ class ShopGameInfo(QWidget, Ui_shop_info):
self.request.deleteLater()
def image_loaded(self):
if self.image_request and self.image_request.error() == QNetworkReply.NoError:
data = self.image_request.readAll().data()
pixmap = QPixmap()
pixmap.loadFromData(data)
self.image.setPixmap(pixmap.scaled(240, 320, transformMode=Qt.SmoothTransformation))
self.image_stack.setCurrentIndex(0)
else:
logger.error("Load image failed")
def button_clicked(self):
webbrowser.open("https://www.epicgames.com/store/de/p/" + self.slug)

View file

@ -13,7 +13,7 @@ from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkRepl
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout, QCompleter
from rare.ui.components.tabs.store.store import Ui_ShopWidget
from rare.utils.extra_widgets import WaitingSpinner
from rare.utils.extra_widgets import WaitingSpinner, ImageLabel
from rare.utils.utils import get_lang
@ -55,7 +55,6 @@ class ShopWidget(QWidget, Ui_ShopWidget):
if self.free_game_request.error() == QNetworkReply.NoError:
try:
free_games = json.loads(self.free_game_request.readAll().data().decode())
print(free_games)
except JSONDecodeError:
return
else:
@ -177,7 +176,15 @@ class GameWidget(QWidget):
def __init__(self, json_info, path: str):
super(GameWidget, self).__init__()
self.layout = QVBoxLayout()
self.image = QLabel()
self.image = ImageLabel()
for img in json_info["keyImages"]:
if img["type"] in ["DieselStoreFrontWide", "VaultClosed"]:
width = 300
self.image.update_image(img["url"], json_info["title"], (width, int(width * 9 / 16)))
break
else:
print("No image found")
self.slug = json_info["productSlug"]
self.title = json_info["title"]
if not os.path.exists(p := os.path.join(path, f"{json_info['title']}.png")):

View file

@ -24,15 +24,6 @@ class Ui_shop_info(object):
self.horizontalLayout.setObjectName("horizontalLayout")
self.image_stack = QtWidgets.QStackedWidget(shop_info)
self.image_stack.setObjectName("image_stack")
self.page = QtWidgets.QWidget()
self.page.setObjectName("page")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.page)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.image = QtWidgets.QLabel(self.page)
self.image.setMinimumSize(QtCore.QSize(240, 320))
self.image.setObjectName("image")
self.verticalLayout_3.addWidget(self.image)
self.image_stack.addWidget(self.page)
self.horizontalLayout.addWidget(self.image_stack)
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
@ -69,14 +60,13 @@ class Ui_shop_info(object):
self.verticalLayout.addItem(spacerItem2)
self.retranslateUi(shop_info)
self.image_stack.setCurrentIndex(0)
self.image_stack.setCurrentIndex(-1)
QtCore.QMetaObject.connectSlotsByName(shop_info)
def retranslateUi(self, shop_info):
_translate = QtCore.QCoreApplication.translate
shop_info.setWindowTitle(_translate("shop_info", "Form"))
self.back_button.setText(_translate("shop_info", "Back"))
self.image.setText(_translate("shop_info", "TextLabel"))
self.title.setText(_translate("shop_info", "Error"))
self.dev.setText(_translate("shop_info", "TextLabel"))
self.price.setText(_translate("shop_info", "TextLabel"))

View file

@ -26,25 +26,8 @@
<item>
<widget class="QStackedWidget" name="image_stack">
<property name="currentIndex">
<number>0</number>
<number>-1</number>
</property>
<widget class="QWidget" name="page">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="image">
<property name="minimumSize">
<size>
<width>240</width>
<height>320</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>

View file

@ -1,7 +1,8 @@
import os
from PyQt5.QtCore import Qt, QRect, QSize, QPoint, pyqtSignal
from PyQt5.QtGui import QMovie
from PyQt5.QtCore import Qt, QRect, QSize, QPoint, pyqtSignal, QUrl
from PyQt5.QtGui import QMovie, QPixmap
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
from PyQt5.QtWidgets import QLayout, QStyle, QSizePolicy, QLabel, QFileDialog, QHBoxLayout, QWidget, QPushButton, \
QStyleOptionTab, QStylePainter, QTabBar
from qtawesome import icon
@ -250,3 +251,41 @@ class SelectViewWidget(QWidget):
self.list_view.setIcon(icon("fa5s.list", color="orange"))
self.icon_view = True
self.toggled.emit()
class ImageLabel(QLabel):
def __init__(self):
super(ImageLabel, self).__init__()
path = os.path.expanduser("~/.cache/rare/cache")
if p := os.environ.get("XDG_CACHE_HOME"):
path = p
self.path = path
self.manager = QNetworkAccessManager()
def update_image(self, url, name, size: tuple = (240, 320)):
self.setFixedSize(*size)
self.img_size = size
self.name = name
for c in r'<>?":|\/* ':
self.name = self.name.replace(c, "")
if not os.path.exists(os.path.join(self.path, self.name+".png")):
self.request = self.manager.get(QNetworkRequest(QUrl(url)))
self.request.finished.connect(self.image_ready)
else:
self.show_image()
def image_ready(self):
if self.request:
if self.request.error() == QNetworkReply.NoError:
with open(os.path.join(self.path, self.name + ".png"), "wb") as file:
file.write(self.request.readAll().data())
file.close()
self.show_image()
else:
return
def show_image(self):
self.image = QPixmap(os.path.join(self.path, self.name + ".png")).scaled(*self.img_size,
transformMode=Qt.SmoothTransformation)
self.setPixmap(self.image)