Nice look of search results; better look for shop info; added ImageLabel in extra_widgets.py
This commit is contained in:
parent
9d02187d2f
commit
337b738599
6 changed files with 120 additions and 71 deletions
|
@ -1,33 +1,43 @@
|
||||||
from PyQt5 import QtGui
|
from PyQt5 import QtGui
|
||||||
from PyQt5.QtCore import pyqtSignal
|
from PyQt5.QtCore import pyqtSignal, Qt
|
||||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QScrollArea, QGroupBox
|
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)
|
show_info = pyqtSignal(dict)
|
||||||
|
|
||||||
# TODO nice look
|
# TODO nice look
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(SearchResults, self).__init__()
|
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.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.widget.setLayout(self.layout)
|
||||||
self.setWidget(self.widget)
|
|
||||||
self.setWidgetResizable(True)
|
self.setLayout(self.main_layout)
|
||||||
|
|
||||||
def show_results(self, results: list):
|
def show_results(self, results: list):
|
||||||
QVBoxLayout().addWidget(self.widget)
|
QVBoxLayout().addWidget(self.widget)
|
||||||
self.widget = QWidget()
|
self.widget = QWidget()
|
||||||
self.layout = QVBoxLayout()
|
self.layout = FlowLayout()
|
||||||
for i in range(self.layout.count()):
|
|
||||||
self.layout.removeItem(i)
|
|
||||||
for res in results:
|
for res in results:
|
||||||
w = _SearchResultItem(res)
|
w = _SearchResultItem(res)
|
||||||
w.show_info.connect(self.show_info.emit)
|
w.show_info.connect(self.show_info.emit)
|
||||||
self.layout.addWidget(w)
|
self.layout.addWidget(w)
|
||||||
self.layout.addStretch(1)
|
|
||||||
self.widget.setLayout(self.layout)
|
self.widget.setLayout(self.layout)
|
||||||
self.setWidget(self.widget)
|
self.result_area.setWidget(self.widget)
|
||||||
|
|
||||||
|
|
||||||
class _SearchResultItem(QGroupBox):
|
class _SearchResultItem(QGroupBox):
|
||||||
|
@ -36,17 +46,41 @@ class _SearchResultItem(QGroupBox):
|
||||||
|
|
||||||
def __init__(self, result: dict):
|
def __init__(self, result: dict):
|
||||||
super(_SearchResultItem, self).__init__()
|
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.res = result
|
||||||
self.title = QLabel(self.res["title"])
|
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)
|
self.layout.addWidget(self.title)
|
||||||
original_price = result['price']['totalPrice']['fmtPrice']['originalPrice']
|
price = result['price']['totalPrice']['fmtPrice']['originalPrice']
|
||||||
self.price = QLabel(f"{self.tr('Original price: ')}{original_price}")
|
discount_price = result['price']['totalPrice']['fmtPrice']['discountPrice']
|
||||||
self.layout.addWidget(self.price)
|
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.setLayout(self.layout)
|
||||||
|
|
||||||
|
self.setFixedWidth(260)
|
||||||
|
|
||||||
def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None:
|
def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None:
|
||||||
if a0.button() == 1:
|
if a0.button() == 1:
|
||||||
self.show_info.emit(self.res)
|
self.show_info.emit(self.res)
|
||||||
|
|
|
@ -2,16 +2,15 @@ import json
|
||||||
import logging
|
import logging
|
||||||
import webbrowser
|
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.QtGui import QPixmap, QFont
|
||||||
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
||||||
from PyQt5.QtWidgets import QWidget, QLabel
|
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.components.tabs.shop.shop_models import ShopGame
|
||||||
from rare.ui.components.tabs.store.shop_game_info import Ui_shop_info
|
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")
|
logger = logging.getLogger("ShopInfo")
|
||||||
|
|
||||||
|
@ -25,6 +24,8 @@ class ShopGameInfo(QWidget, Ui_shop_info):
|
||||||
super(ShopGameInfo, self).__init__()
|
super(ShopGameInfo, self).__init__()
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.open_store_button.clicked.connect(self.button_clicked)
|
self.open_store_button.clicked.connect(self.button_clicked)
|
||||||
|
self.image = ImageLabel()
|
||||||
|
self.image_stack.addWidget(self.image)
|
||||||
self.image_stack.addWidget(WaitingSpinner())
|
self.image_stack.addWidget(WaitingSpinner())
|
||||||
self.manager = QNetworkAccessManager()
|
self.manager = QNetworkAccessManager()
|
||||||
|
|
||||||
|
@ -48,7 +49,6 @@ class ShopGameInfo(QWidget, Ui_shop_info):
|
||||||
|
|
||||||
# init API request
|
# init API request
|
||||||
locale = get_lang()
|
locale = get_lang()
|
||||||
locale = "en"
|
|
||||||
url = f"https://store-content.ak.epicgames.com/api/{locale}/content/{'products' if not is_bundle else 'bundles'}/{slug}"
|
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)
|
# game = api_utils.get_product(slug, locale)
|
||||||
self.request = self.manager.get(QNetworkRequest(QUrl(url)))
|
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.title.setText(self.game.title)
|
||||||
|
|
||||||
self.price.setText(self.game.price)
|
self.price.setText(self.game.price)
|
||||||
|
if self.game.price != self.game.discount_price:
|
||||||
self.discount_price.setText(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)
|
# print(self.game.reqs)
|
||||||
bold_font = QFont()
|
bold_font = QFont()
|
||||||
bold_font.setBold(True)
|
bold_font.setBold(True)
|
||||||
|
@ -88,16 +92,19 @@ class ShopGameInfo(QWidget, Ui_shop_info):
|
||||||
self.req_group_box.layout().addWidget(rec_label, 0, 2)
|
self.req_group_box.layout().addWidget(rec_label, 0, 2)
|
||||||
|
|
||||||
for i, (key, value) in enumerate(self.game.reqs["Windows"].items()):
|
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 = QLabel(value[0])
|
||||||
min_label.setWordWrap(True)
|
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 = QLabel(value[1])
|
||||||
rec_label.setWordWrap(True)
|
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.update_image(self.game.image_urls.front_tall, self.game.title, (240, 320))
|
||||||
self.image_request.finished.connect(self.image_loaded)
|
|
||||||
|
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:
|
try:
|
||||||
if isinstance(self.game.developer, list):
|
if isinstance(self.game.developer, list):
|
||||||
|
@ -111,16 +118,5 @@ class ShopGameInfo(QWidget, Ui_shop_info):
|
||||||
|
|
||||||
self.request.deleteLater()
|
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):
|
def button_clicked(self):
|
||||||
webbrowser.open("https://www.epicgames.com/store/de/p/" + self.slug)
|
webbrowser.open("https://www.epicgames.com/store/de/p/" + self.slug)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkRepl
|
||||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout, QCompleter
|
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout, QCompleter
|
||||||
|
|
||||||
from rare.ui.components.tabs.store.store import Ui_ShopWidget
|
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
|
from rare.utils.utils import get_lang
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,7 +55,6 @@ class ShopWidget(QWidget, Ui_ShopWidget):
|
||||||
if self.free_game_request.error() == QNetworkReply.NoError:
|
if self.free_game_request.error() == QNetworkReply.NoError:
|
||||||
try:
|
try:
|
||||||
free_games = json.loads(self.free_game_request.readAll().data().decode())
|
free_games = json.loads(self.free_game_request.readAll().data().decode())
|
||||||
print(free_games)
|
|
||||||
except JSONDecodeError:
|
except JSONDecodeError:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
@ -177,7 +176,15 @@ class GameWidget(QWidget):
|
||||||
def __init__(self, json_info, path: str):
|
def __init__(self, json_info, path: str):
|
||||||
super(GameWidget, self).__init__()
|
super(GameWidget, self).__init__()
|
||||||
self.layout = QVBoxLayout()
|
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.slug = json_info["productSlug"]
|
||||||
self.title = json_info["title"]
|
self.title = json_info["title"]
|
||||||
if not os.path.exists(p := os.path.join(path, f"{json_info['title']}.png")):
|
if not os.path.exists(p := os.path.join(path, f"{json_info['title']}.png")):
|
||||||
|
|
|
@ -24,15 +24,6 @@ class Ui_shop_info(object):
|
||||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||||
self.image_stack = QtWidgets.QStackedWidget(shop_info)
|
self.image_stack = QtWidgets.QStackedWidget(shop_info)
|
||||||
self.image_stack.setObjectName("image_stack")
|
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.horizontalLayout.addWidget(self.image_stack)
|
||||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
|
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
|
||||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||||
|
@ -69,14 +60,13 @@ class Ui_shop_info(object):
|
||||||
self.verticalLayout.addItem(spacerItem2)
|
self.verticalLayout.addItem(spacerItem2)
|
||||||
|
|
||||||
self.retranslateUi(shop_info)
|
self.retranslateUi(shop_info)
|
||||||
self.image_stack.setCurrentIndex(0)
|
self.image_stack.setCurrentIndex(-1)
|
||||||
QtCore.QMetaObject.connectSlotsByName(shop_info)
|
QtCore.QMetaObject.connectSlotsByName(shop_info)
|
||||||
|
|
||||||
def retranslateUi(self, shop_info):
|
def retranslateUi(self, shop_info):
|
||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
shop_info.setWindowTitle(_translate("shop_info", "Form"))
|
shop_info.setWindowTitle(_translate("shop_info", "Form"))
|
||||||
self.back_button.setText(_translate("shop_info", "Back"))
|
self.back_button.setText(_translate("shop_info", "Back"))
|
||||||
self.image.setText(_translate("shop_info", "TextLabel"))
|
|
||||||
self.title.setText(_translate("shop_info", "Error"))
|
self.title.setText(_translate("shop_info", "Error"))
|
||||||
self.dev.setText(_translate("shop_info", "TextLabel"))
|
self.dev.setText(_translate("shop_info", "TextLabel"))
|
||||||
self.price.setText(_translate("shop_info", "TextLabel"))
|
self.price.setText(_translate("shop_info", "TextLabel"))
|
||||||
|
|
|
@ -26,25 +26,8 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QStackedWidget" name="image_stack">
|
<widget class="QStackedWidget" name="image_stack">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>-1</number>
|
||||||
</property>
|
</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>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt, QRect, QSize, QPoint, pyqtSignal
|
from PyQt5.QtCore import Qt, QRect, QSize, QPoint, pyqtSignal, QUrl
|
||||||
from PyQt5.QtGui import QMovie
|
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, \
|
from PyQt5.QtWidgets import QLayout, QStyle, QSizePolicy, QLabel, QFileDialog, QHBoxLayout, QWidget, QPushButton, \
|
||||||
QStyleOptionTab, QStylePainter, QTabBar
|
QStyleOptionTab, QStylePainter, QTabBar
|
||||||
from qtawesome import icon
|
from qtawesome import icon
|
||||||
|
@ -250,3 +251,41 @@ class SelectViewWidget(QWidget):
|
||||||
self.list_view.setIcon(icon("fa5s.list", color="orange"))
|
self.list_view.setIcon(icon("fa5s.list", color="orange"))
|
||||||
self.icon_view = True
|
self.icon_view = True
|
||||||
self.toggled.emit()
|
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)
|
||||||
|
|
Loading…
Reference in a new issue