Skip to content

Commit 5930a95

Browse files
committed
Init commit
0 parents  commit 5930a95

File tree

10 files changed

+655
-0
lines changed

10 files changed

+655
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea
2+
ui/add_game_dialog.ui
3+
ui/mainWindow.ui
4+
venv

dark.qss

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
QMainWindow {
2+
background-color: #2b2b2b; /* Тёмно-серый фон */
3+
}
4+
/* Стиль для всего меню-бара */
5+
QMenuBar {
6+
background-color: #3c3f41;
7+
color: #a9b7c6;
8+
}
9+
/* Стиль для отдельного пункта меню (Файл, Правка...) */
10+
QMenuBar::item {
11+
background-color: transparent; /* Прозрачный фон */
12+
}
13+
/* Стиль для пункта меню при его выборе */
14+
QMenuBar::item:selected {
15+
background-color: #555;
16+
}
17+
/* Стиль для выпадающего меню */
18+
QMenu {
19+
background-color: #3c3f41;
20+
color: #a9b7c6;
21+
border: 1px solid #555;
22+
}
23+
/* Стиль для пунктов в выпадающем меню при наведении */
24+
QMenu::item:selected {
25+
background-color: #555;
26+
}
27+
/* Стиль для кнопок */
28+
QPushButton {
29+
background-color: #3c3f41;
30+
color: #a9b7c6;
31+
border: 1px solid #555;
32+
border-radius: 5px;
33+
padding: 5px 10px;
34+
}
35+
/* Стиль для кнопок при наведении мышки */
36+
QPushButton:hover {
37+
border: 2px solid #3498db; /* Синяя рамка */
38+
border-radius: 10px;
39+
}
40+
/* Стиль для кнопок при клике мышки */
41+
QPushButton:pressed {
42+
border: 2px solid #2980b9; /* Тёмно-синяя рамка */
43+
border-radius: 10px;
44+
}

db.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import os
2+
import sqlite3
3+
from pathlib import Path
4+
5+
6+
def get_data_path():
7+
documents_path = Path.home() / 'Documents'
8+
data_path = documents_path / 'QtLauncher_Data'
9+
data_path.mkdir(exist_ok=True)
10+
return data_path
11+
12+
13+
class Database:
14+
def __init__(self):
15+
self.data_path = get_data_path()
16+
self.db_path = self.data_path / 'games.db'
17+
self.create_tables()
18+
19+
def get_connection(self):
20+
return sqlite3.connect(self.db_path)
21+
22+
def create_tables(self):
23+
conn = self.get_connection()
24+
cursor = conn.cursor()
25+
cursor.execute(
26+
'''CREATE TABLE IF NOT EXISTS Games (
27+
id INTEGER PRIMARY KEY AUTOINCREMENT,
28+
name TEXT NOT NULL UNIQUE,
29+
path TEXT NOT NULL UNIQUE
30+
)'''
31+
)
32+
conn.commit()
33+
conn.close()
34+
35+
def check_name_is_unique(self, name):
36+
conn = self.get_connection()
37+
cursor = conn.cursor()
38+
cursor.execute(
39+
"SELECT COUNT(*) FROM Games WHERE name = ?", (name,)
40+
)
41+
count = cursor.fetchone()[0]
42+
return count == 0
43+
44+
def check_path_is_unique(self, game_path):
45+
conn = self.get_connection()
46+
cursor = conn.cursor()
47+
cursor.execute(
48+
"SELECT COUNT(*) FROM Games WHERE path = ?", (game_path,)
49+
)
50+
count = cursor.fetchone()[0]
51+
return count == 0
52+
53+
def insert_game(self, name, game_path):
54+
conn = self.get_connection()
55+
cursor = conn.cursor()
56+
try:
57+
cursor.execute(
58+
"INSERT INTO Games (name, path) VALUES (?, ?)",
59+
(name, game_path)
60+
)
61+
conn.commit()
62+
print(f"Игра '{name}' добавлена в базу данных")
63+
except sqlite3.IntegrityError:
64+
print(f"Ошибка: игра с именем '{name}' уже существует")
65+
except Exception as e:
66+
print(f"Ошибка при добавлении игры: {e}")
67+
finally:
68+
conn.close()
69+
70+
def delete_game(self, name):
71+
conn = self.get_connection()
72+
cursor = conn.cursor()
73+
cursor.execute(
74+
"DELETE FROM Games WHERE name = ?",
75+
(name,)
76+
)
77+
conn.commit()
78+
conn.close()
79+
80+
def get_games(self):
81+
conn = self.get_connection()
82+
cursor = conn.cursor()
83+
cursor.execute("SELECT name FROM Games")
84+
games = cursor.fetchall()
85+
conn.close()
86+
87+
game_names = [game[0] for game in games]
88+
return game_names
89+
90+
def get_game(self, name):
91+
conn = self.get_connection()
92+
cursor = conn.cursor()
93+
cursor.execute(
94+
"SELECT * FROM Games WHERE name = ?",
95+
(name,)
96+
)
97+
row = cursor.fetchone()
98+
conn.close()
99+
return row
100+
101+
102+
database = Database()

dialogs.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from PyQt6.QtWidgets import QDialog, QFileDialog, QMessageBox
2+
3+
from db import database
4+
from ui.add_game_dialog_ui import Ui_Dialog
5+
6+
7+
class AddGameDialog(QDialog, Ui_Dialog):
8+
def __init__(self):
9+
super().__init__()
10+
self.setFixedSize(450, 120)
11+
12+
self.setupUi(self)
13+
self.path_button.clicked.connect(self.choose_file)
14+
15+
self.buttonBox.accepted.disconnect()
16+
self.buttonBox.rejected.disconnect()
17+
18+
self.buttonBox.accepted.connect(self.accept_dialog)
19+
self.buttonBox.rejected.connect(self.reject)
20+
21+
def choose_file(self):
22+
file_path = QFileDialog.getOpenFileName(
23+
self, 'Выбрать файл', '',
24+
'EXE - Файл (*.exe)')[0]
25+
if file_path:
26+
self.file_path.setText(file_path)
27+
28+
def accept_dialog(self):
29+
game_name = self.game_name.text().strip()
30+
game_path = self.file_path.text().strip()
31+
32+
if not game_name:
33+
QMessageBox.warning(self, "Ошибка", "Введите название игры")
34+
return
35+
36+
if not game_path:
37+
QMessageBox.warning(self, "Ошибка", "Выберите файл игры")
38+
return
39+
40+
if not database.check_name_is_unique(game_name):
41+
QMessageBox.warning(self, "Ошибка",
42+
"Игра с таким именем уже существует")
43+
return
44+
45+
if not database.check_path_is_unique(game_path):
46+
QMessageBox.warning(self, "Ошибка",
47+
"Игра с таким путём уке существует")
48+
return
49+
50+
try:
51+
database.insert_game(game_name, game_path)
52+
self.accept()
53+
QMessageBox.information(self, "Успех", "Игра добавлена!")
54+
55+
except Exception as e:
56+
QMessageBox.critical(self, "Ошибка",
57+
f"Не удалось добавить игру: {str(e)}")

light.qss

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
QMainWindow {
2+
background-color: #f4f4f4; /* Светло-серый фон */
3+
}
4+
5+
/* Меню-бар */
6+
QMenuBar {
7+
background-color: #e6e6e6;
8+
color: #2b2b2b;
9+
}
10+
11+
/* Пункты меню */
12+
QMenuBar::item {
13+
background-color: transparent;
14+
}
15+
16+
/* Пункт меню при наведении */
17+
QMenuBar::item:selected {
18+
background-color: #d0d0d0;
19+
}
20+
21+
/* Выпадающее меню */
22+
QMenu {
23+
background-color: #ffffff;
24+
color: #2b2b2b;
25+
border: 1px solid #cccccc;
26+
}
27+
28+
/* Пункты в выпадающем меню при наведении */
29+
QMenu::item:selected {
30+
background-color: #dceeff; /* Нежно-голубой фон при наведении */
31+
}
32+
33+
/* Кнопки */
34+
QPushButton {
35+
background-color: #e6e6e6;
36+
color: #2b2b2b;
37+
border: 1px solid #bbbbbb;
38+
border-radius: 5px;
39+
padding: 5px 10px;
40+
}
41+
42+
/* Кнопки при наведении */
43+
QPushButton:hover {
44+
border: 2px solid #3498db; /* Синяя рамка */
45+
border-radius: 10px;
46+
}
47+
48+
/* Кнопки при нажатии */
49+
QPushButton:pressed {
50+
border: 2px solid #2980b9; /* Тёмно-синяя рамка */
51+
border-radius: 10px;
52+
background-color: #d9eaff;
53+
}
54+
55+
/* Метки (Label) */
56+
QLabel {
57+
color: #000000; /* Чёрный текст */
58+
}
59+
60+
/* Список (ListWidget) */
61+
QListWidget {
62+
background-color: #eeeeee; /* Светло-серый фон */
63+
color: #2b2b2b; /* Тёмно-серый текст */
64+
border: 1px solid #cccccc;
65+
border-radius: 5px;
66+
}
67+
68+
/* Элементы списка при наведении */
69+
QListWidget::item:hover {
70+
background-color: #dceeff; /* Голубой оттенок при наведении */
71+
}
72+
73+
/* Выбранный элемент */
74+
QListWidget::item:selected {
75+
background-color: #cce4ff; /* Чуть ярче при выборе */
76+
color: #000000;
77+
}

main.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import os
2+
import sys
3+
4+
from PyQt6.QtWidgets import QApplication, QMainWindow, QMessageBox
5+
6+
import dialogs
7+
from db import database
8+
from ui.mainWindow_ui import Ui_MainWindow
9+
from utils import create_json, get_theme, update_setting, add_game_to_history, \
10+
get_last_games, create_txt
11+
12+
13+
class QtLauncher(QMainWindow, Ui_MainWindow):
14+
def __init__(self):
15+
super().__init__()
16+
self.setFixedSize(750, 420)
17+
18+
self.setupUi(self)
19+
self.update_game_list()
20+
21+
create_txt()
22+
self.update_last_game_list()
23+
24+
create_json()
25+
26+
with open(f'{get_theme()}.qss') as qss:
27+
self.setStyleSheet(qss.read())
28+
29+
self.add_game.clicked.connect(self.open_dialog)
30+
self.list_games.itemDoubleClicked.connect(self.open_game)
31+
self.delete_game.clicked.connect(self.delete_game_from_list)
32+
33+
self.sort_name_a_z.clicked.connect(lambda: self.sort_games(""))
34+
self.sort_name_z_a.clicked.connect(lambda: self.sort_games("r"))
35+
36+
self.action_2.triggered.connect(lambda: self.set_theme("light"))
37+
self.action_3.triggered.connect(lambda: self.set_theme("dark"))
38+
39+
def set_theme(self, theme):
40+
with open(f'{theme}.qss') as qss:
41+
self.setStyleSheet(qss.read())
42+
update_setting("theme", theme)
43+
44+
def update_game_list(self):
45+
games = database.get_games()
46+
self.list_games.clear()
47+
for game in games:
48+
self.list_games.addItem(game)
49+
50+
def update_last_game_list(self):
51+
games = get_last_games()
52+
self.last_games.clear()
53+
for game in games:
54+
self.last_games.addItem(game)
55+
56+
def sort_games(self, mode):
57+
games = database.get_games()
58+
sorted_games = sorted(games, reverse=(mode == "r"))
59+
self.list_games.clear()
60+
for game in sorted_games:
61+
self.list_games.addItem(game)
62+
63+
def delete_game_from_list(self):
64+
current_item = self.list_games.currentItem()
65+
if current_item:
66+
game_name = current_item.text()
67+
database.delete_game(game_name)
68+
current_row = self.list_games.currentRow()
69+
self.list_games.takeItem(current_row)
70+
self.list_games.clearSelection()
71+
72+
def open_game(self, item):
73+
game = database.get_game(item.text())
74+
try:
75+
add_game_to_history(game[1])
76+
os.startfile(game[2])
77+
except Exception as e:
78+
QMessageBox.warning(self, "Ошибка!", str(e))
79+
self.update_last_game_list()
80+
81+
def open_dialog(self):
82+
dialog = dialogs.AddGameDialog()
83+
dialog.exec()
84+
self.update_game_list()
85+
86+
87+
if __name__ == '__main__':
88+
app = QApplication(sys.argv)
89+
wind = QtLauncher()
90+
wind.show()
91+
sys.exit(app.exec())

ui/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)