Skip to content

Commit

Permalink
Merge pull request #3 from Lioheart/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Lioheart authored May 28, 2020
2 parents 7bfb123 + 38f3537 commit 3bcbb2c
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 51 deletions.
15 changes: 10 additions & 5 deletions compress_txt.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,16 @@ def gzip_read(q=None, outfilename='example.txt.gz'):
:return: tekst źródłowy
:param outfilename: nazwa pliku
"""
with gzip.open(outfilename, 'rb') as input_file:
with io.TextIOWrapper(input_file, encoding='utf-8') as dec:
if q:
q.put(dec.read())
return dec.read()
try:
with gzip.open(outfilename, 'rb') as input_file:
with io.TextIOWrapper(input_file, encoding='utf-8') as dec:
if q:
q.put(dec.read())
return dec.read()
except FileNotFoundError:
if q:
q.put('Nie znaleziono pliku!')
return 'Nie znaleziono pliku!'


if __name__ == '__main__':
Expand Down
56 changes: 32 additions & 24 deletions notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@


class NotificationIcon:
"""
Odpowiada za ikony notyfikacji
"""
Info, Success, Warning, Error, Close = range(5)
Types = {
Info: None,
Expand All @@ -37,6 +40,9 @@ class NotificationIcon:

@classmethod
def init(cls):
"""
Inicjalizuje proces
"""
cls.Types[cls.Info] = QPixmap(QImage.fromData(base64.b64decode(
'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAC5ElEQVRYR8VX0VHbQBB9e/bkN3QQU0FMBSEVYFcQ8xPBJLJ1FWAqOMcaxogfTAWQCiAVRKkgTgfmM4zRZu6QhGzL0p0nDPr17e7bt7tv14RX/uiV48MJgAon+8TiAMRtMFogaqUJxADPwRRzg67kl8+xbWJWANR40iPQSSFgtX/mGQkaDr56V3VAKgGos4s2JXwJoF3naMPvMS+SrpTHs032GwGkdF+DsFMVnJm/oyGGeHico0EjIjpYes+YMyVd6R/flfkpBWCCQ9zaZM2LZDfLMGXsZ5kdI/lYBmINgHHyyLd1mWdBbAFAM/GY7K2WYx1AeB4T6L1N9umbGxZ0qktATaEAdCps48D39oq/LwEw3U5CN92LfczJoewfT7MAywDCaEbAuxeLrh0zz4L+0e4aAJfGy+sP3IMxlH1vpMJoSMCJDXgWtJeJVc6ACs9HBBrYODCJAFdYvAmkPJxnNqMwYht7Bn+T/lGg3z4DGEd3RPhQ54DBvwAOVkeqagRXfTLjh+x7+8sALOtfHLuiYzWOAiLoKbD58mnIGbCmLxUepS6NQmYlUGE0JeCTTXT9JvA9E9sZgO5iIpoyc6/YzcqSwQzgGgBXB7oXpH9klpRSkxY1xW/b7Iu2zk34PILPnazCqEPAtTWA8iZ0HsOu9L0bw4DzCJeNocMGNDpQ3IKO+6NUiJ4ysZNiBv5I3zPnmJmG5oM+wbS+9+qkvGi7NAXGmeUy0ioofa+XA0jH0UaMKpdRWs/adcwMqfV/tenqpqHY/Znt+j2gJi00RUzA201dXaxh9iZdZloJS+9H1otrkbRrD5InFqpPskxEshJQ468CkSmJC+i1HigaaxCAuCljgoDhwPdOjf7rFVxxuJrMkXScjtKc1rOLNpJk6nii5XmYzbngzlZn+RIb40kPJPTBYXUt6VEDJ8Pi6bWpNFb/jFYY6YGpDeKdjBmTKdMcxDGEmP73v2a2Gr/NOycGtglQZ/MPzEqCMLGckJEAAAAASUVORK5CYII=')))
cls.Types[cls.Success] = QPixmap(QImage.fromData(base64.b64decode(
Expand All @@ -50,27 +56,35 @@ def init(cls):

@classmethod
def icon(cls, ntype):
"""
Metoda odpowiedzialna za wybranie odpowiedniej ikony
:param ntype:
:return: ikona
"""
return cls.Types.get(ntype)


class NotificationItem(QWidget):
"""
Klasa reprezentująca pojedynczy dymek
"""
closed = Signal(QListWidgetItem)

def __init__(self, title, message, item, *args, ntype=0, callback=None, **kwargs):
super(NotificationItem, self).__init__(*args, **kwargs)
self.item = item
self.callback = callback
layout = QHBoxLayout(self, spacing=0)
layout.setContentsMargins(0, 0, 0, 0)
lhbox = QHBoxLayout(self, spacing=0)
lhbox.setContentsMargins(0, 0, 0, 0)
self.bgWidget = QWidget(self) # 背景控件, 用于支持动画效果
layout.addWidget(self.bgWidget)
lhbox.addWidget(self.bgWidget)

layout = QGridLayout(self.bgWidget)
layout.setHorizontalSpacing(15)
layout.setVerticalSpacing(10)
lgbox = QGridLayout(self.bgWidget)
lgbox.setHorizontalSpacing(15)
lgbox.setVerticalSpacing(10)

# 标题左边图标
layout.addWidget(
lgbox.addWidget(
QLabel(self, pixmap=NotificationIcon.icon(ntype)), 0, 0)

# 标题
Expand All @@ -93,11 +107,11 @@ def __init__(self, title, message, item, *args, ntype=0, callback=None, **kwargs
self.labelMessage.adjustSize()

# 添加到布局
layout.addWidget(self.labelTitle, 0, 1)
layout.addItem(QSpacerItem(
lgbox.addWidget(self.labelTitle, 0, 1)
lgbox.addItem(QSpacerItem(
40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum), 0, 2)
layout.addWidget(self.labelClose, 0, 3)
layout.addWidget(self.labelMessage, 1, 1, 1, 2)
lgbox.addWidget(self.labelClose, 0, 3)
lgbox.addWidget(self.labelMessage, 1, 1, 1, 2)

# 边框阴影
effect = QGraphicsDropShadowEffect(self)
Expand All @@ -111,21 +125,15 @@ def __init__(self, title, message, item, *args, ntype=0, callback=None, **kwargs
# 5秒自动关闭
self._timer = QTimer(self, timeout=self.doClose)
self._timer.setSingleShot(True) # 只触发一次
self._timer.start(6000)
self._timer.start(12000)

def doClose(self):
try:
# 可能由于手动点击导致item已经被删除了
self.closed.emit(self.item)
except:
pass
self.closed.emit(self.item)

def showAnimation(self, width):
# 显示动画
pass

def closeAnimation(self):
# 关闭动画
pass

def mousePressEvent(self, event):
Expand Down Expand Up @@ -153,6 +161,9 @@ def paintEvent(self, event):


class NotificationWindow(QListWidget):
"""
Klasa odpowiedznialna za wyswietlanie listy powiadomień
"""
_instance = None

def __init__(self, *args, **kwargs):
Expand All @@ -161,9 +172,7 @@ def __init__(self, *args, **kwargs):
self.setMinimumWidth(412)
self.setMaximumWidth(412)
# QApplication.instance().setQuitOnLastWindowClosed(True)
# 隐藏任务栏,无边框,置顶等
self.setWindowFlags(self.windowFlags() | Qt.Tool |
Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setWindowFlags(self.windowFlags() | Qt.Tool | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
# 去掉窗口边框
self.setFrameShape(self.NoFrame)
# 背景透明
Expand All @@ -182,10 +191,9 @@ def removeItem(self, item):
# 删除item
w = self.itemWidget(item)
self.removeItemWidget(item)
item = self.takeItem(self.indexFromItem(item).row())
self.takeItem(self.indexFromItem(item).row())
w.close()
w.deleteLater()
del item

@classmethod
def _createInstance(cls):
Expand Down
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
PySide2~=5.14.2.1
PySide2~=5.14.2.1
bs4~=0.0.1
beautifulsoup4~=4.9.0
Binary file modified resources/descriptions/arcane.txt.gz
Binary file not shown.
Binary file added resources/descriptions/desc_magic.txt.gz
Binary file not shown.
Binary file modified resources/descriptions/divine.txt.gz
Binary file not shown.
Binary file modified resources/descriptions/magic.txt.gz
Binary file not shown.
Binary file modified resources/descriptions/power.txt.gz
Binary file not shown.
3 changes: 1 addition & 2 deletions src/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
"""
Inicjalizacja wstępnych parametrów
"""
import os.path

__author__ = "Jakub Hawro"
__copyright__ = "Copyright 2020-2020 Jakub Hawro (The Compiler)"
__license__ = "MIT"
__maintainer__ = __author__
__email__ = "[email protected]"
__version__ = "0.0.2"
__version__ = "0.0.3"
__version_info__ = tuple(int(part) for part in __version__.split('.'))
__description__ = "Lista zaklęć z settingu D&D 3.5."

Expand Down
53 changes: 34 additions & 19 deletions src/spells.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from PySide2.QtGui import QIcon, QFont, QPalette, QColor, QBrush
from PySide2.QtWidgets import QWidget, QApplication, QVBoxLayout, QHBoxLayout, QTextBrowser, QPushButton, \
QGraphicsDropShadowEffect
from bs4 import BeautifulSoup

from compress_txt import gzip_read

Expand Down Expand Up @@ -87,7 +88,7 @@ def initUI(self):
self.btn_subback.setIcon(icon)
icon.addFile('./resources/icons/arrow-left-solid.svg', QSize(), QIcon.Normal, QIcon.Off)
btn_back.setIcon(icon)
# TODO usuń to po wprowadzeniu odpowiednich wartości w bazie danych
# TODO usuń to po wprowadzeniu odpowiednich wartości czarów w bazie danych
self.btn_list.setEnabled(False)
self.text_desc.setViewportMargins(10, 10, 10, 10)

Expand Down Expand Up @@ -147,8 +148,6 @@ def submenu_create(self, *buttons):
"""
self.vbox_child.addWidget(self.btn_subback)
for btn in buttons:
# TODO usuń to po wprowadzeniu odpowiednich wartości w bazie danych
btn.setDisabled(True)
self.vbox_child.addWidget(btn)

def classes_spells(self):
Expand All @@ -173,6 +172,7 @@ def magic(self):
"""
Odpowiada za wyświetlenie menu funkcjonowania czarów
"""
path = './resources/descriptions/magic.txt.gz'
self.clear_layout()

btn_mag1 = QPushButton('Funkcjonowanie czarowania')
Expand All @@ -185,14 +185,16 @@ def magic(self):
btn_mag8 = QPushButton('Specjalne efekty czarów')
btn_mag9 = QPushButton('Łączenie efektów magicznych')

self.submenu_create(btn_mag1, btn_mag2, btn_mag3, btn_mag4, btn_mag5, btn_mag6, btn_mag7, btn_mag8, btn_mag9)
self.create_btn_connect(path, btn_mag1, btn_mag2, btn_mag3, btn_mag4, btn_mag5, btn_mag6, btn_mag7, btn_mag8,
btn_mag9)

self.description_thread('./resources/descriptions/magic.txt.gz')
self.description_thread(path, 'description')

def description(self):
"""
Odpowiada za wyświetlenie menu opisu zaklęć
"""
path = './resources/descriptions/desc_magic.txt.gz'
self.clear_layout()

btn_desc1 = QPushButton('Nazwa')
Expand All @@ -208,8 +210,8 @@ def description(self):
btn_desc11 = QPushButton('Odporność na czary')
btn_desc12 = QPushButton('Opis działania')

self.submenu_create(btn_desc1, btn_desc2, btn_desc3, btn_desc4, btn_desc5, btn_desc6, btn_desc7, btn_desc8,
btn_desc9, btn_desc10, btn_desc11, btn_desc12)
self.create_btn_connect(path, btn_desc1, btn_desc2, btn_desc3, btn_desc4, btn_desc5, btn_desc6, btn_desc7,
btn_desc8, btn_desc9, btn_desc10, btn_desc11, btn_desc12)

self.text_desc.setText(
'''
Expand All @@ -222,55 +224,68 @@ def arcane(self):
"""
Odpowiada za wyświetlenie menu opisu zaklęć wtajemniczeń
"""
path = './resources/descriptions/arcane.txt.gz'
self.clear_layout()

btn_arc1 = QPushButton('Jak czarodziej przygotowuje zaklęcia')
btn_arc2 = QPushButton('Magiczne zapiski wtajemniczeń')
btn_arc3 = QPushButton('Zaklinacze i bardowie')

self.submenu_create(btn_arc1, btn_arc2, btn_arc3)
self.create_btn_connect(path, btn_arc1, btn_arc2, btn_arc3)

self.description_thread('./resources/descriptions/arcane.txt.gz')
self.description_thread(path, 'description')

def divine(self):
"""
Odpowiada za wyświetlenie menu opisu zakleć objawień
"""
path = './resources/descriptions/divine.txt.gz'
self.clear_layout()

btn_div1 = QPushButton('Jak przygotowuje się zaklęcia objawień')
btn_div2 = QPushButton('Magiczne zapiski objawień')
btn_div3 = QPushButton('Nowe czary objawień')

self.submenu_create(btn_div1, btn_div2, btn_div3)

self.description_thread('./resources/descriptions/divine.txt.gz')
self.create_btn_connect(path, btn_div1, btn_div2, btn_div3)
self.description_thread(path, 'description')

def power(self):
"""
Odpowiada za wyświetlenie menu zdolności specjalnych
"""
path = './resources/descriptions/power.txt.gz'
self.clear_layout()

btn_pow1 = QPushButton('Zdolności czaropodobne')
btn_pow2 = QPushButton('Zdolności nadnaturalne')
btn_pow3 = QPushButton('Zdolności nadzwyczajne')
btn_pow4 = QPushButton('Zdolności naturalne')
self.submenu_create()

self.submenu_create(btn_pow1, btn_pow2, btn_pow3, btn_pow4)
self.description_thread(path)

self.description_thread('./resources/descriptions/power.txt.gz')
def create_btn_connect(self, path, *args):
"""
Służy do utworzenia odpowiednich powiązań z przyciskami podmenu. Wymaga ścieżki do pliku z danym opisem
oraz argumentów w postaci przycisków QPushButton
:param path: ścieżka do pliku z opisem
:param args: przyciski QPushButton
"""
self.submenu_create(*args)
for i, val in enumerate(args):
y = 'btn' + str(i + 1)
val.pressed.connect(lambda x=y: self.description_thread(path, x))

def description_thread(self, path):
def description_thread(self, path, bs_id=None):
"""
Wykonuje odczyt opisu danego podrozdziału z pliku, w osobnym wątku
:param bs_id: id div
:param path: ścieżka do pliku z opisem
"""
que = queue.Queue()
x = threading.Thread(target=gzip_read, args=(que, path))
x.start() # Rozpoczyna wątek
x.join() # Kończy wątek. Aby sprawdzić wystarczy x.is_alive()
text = que.get()
if bs_id:
soup = BeautifulSoup(text, 'html.parser') # make soup that is parse-able by bs
text = str(soup.find('div', id=bs_id))
self.text_desc.setHtml(text)


Expand Down

0 comments on commit 3bcbb2c

Please sign in to comment.