You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

296 lines
11 KiB

import sys
import os
import sqlite3
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QPushButton, QVBoxLayout,
QHBoxLayout, QWidget, QLineEdit, QLabel, QMessageBox, QTabWidget, QScrollArea, QFrame, QGridLayout)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
class PokemonEvolutionWidget(QWidget):
def __init__(self, conn, pfic):
super().__init__()
self.conn = conn
self.pfic = pfic
self.layout = QVBoxLayout()
self.setLayout(self.layout)
self.stage_width = 200 # Fixed width for each evolution stage
self.stage_height = 250 # Fixed height for each evolution stage
self.build_evolution_chain()
def build_evolution_chain(self):
chain = self.get_full_evolution_chain(self.pfic)
self.display_evolution_chain(chain)
def get_full_evolution_chain(self, pfic):
cursor = self.conn.cursor()
chain = []
visited = set()
def build_chain(current_pfic):
if current_pfic in visited:
return None
visited.add(current_pfic)
cursor.execute('SELECT name, form_name FROM pokemon_forms WHERE PFIC = ?', (current_pfic,))
pokemon = cursor.fetchone()
if not pokemon:
return None
name, form_name = pokemon
node = {"pfic": current_pfic, "name": name, "form_name": form_name, "evolutions": []}
cursor.execute('''
SELECT ec.to_pfic, pf.name, pf.form_name, ec.method
FROM evolution_chains ec
JOIN pokemon_forms pf ON ec.to_pfic = pf.PFIC
WHERE ec.from_pfic = ?
''', (current_pfic,))
evolutions = cursor.fetchall()
for evo_pfic, evo_name, evo_form, method in evolutions:
evo_node = build_chain(evo_pfic)
if evo_node:
node["evolutions"].append({"node": evo_node, "method": method})
return node
chain = build_chain(pfic)
return chain
def display_evolution_chain(self, chain):
if not chain:
return
main_layout = QHBoxLayout()
self.layout.addLayout(main_layout)
stages = self.split_into_stages(chain)
for stage_index, stage in enumerate(stages):
stage_widget = QWidget()
stage_layout = QGridLayout()
stage_widget.setLayout(stage_layout)
stage_widget.setFixedSize(self.stage_width, self.stage_height * len(stage))
for row, pokemon in enumerate(stage):
pokemon_widget = self.create_pokemon_widget(pokemon["pfic"], pokemon["name"], pokemon["form_name"])
stage_layout.addWidget(pokemon_widget, row, 0, Qt.AlignCenter)
if stage_index < len(stages) - 1 and pokemon.get("method"):
arrow_label = QLabel("")
arrow_label.setStyleSheet("font-size: 24px;")
stage_layout.addWidget(arrow_label, row, 1, Qt.AlignCenter)
method_label = QLabel(pokemon["method"])
method_label.setWordWrap(True)
method_label.setFixedWidth(80)
stage_layout.addWidget(method_label, row, 2, Qt.AlignCenter)
main_layout.addWidget(stage_widget)
def split_into_stages(self, chain):
stages = []
current_stage = [{"pfic": chain["pfic"], "name": chain["name"], "form_name": chain["form_name"]}]
stages.append(current_stage)
while current_stage:
next_stage = []
for pokemon in current_stage:
evolutions = self.get_evolutions(pokemon["pfic"])
for evolution in evolutions:
next_stage.append({
"pfic": evolution["to_pfic"],
"name": evolution["name"],
"form_name": evolution["form_name"],
"method": evolution["method"]
})
if next_stage:
stages.append(next_stage)
current_stage = next_stage
return stages
def get_evolutions(self, pfic):
cursor = self.conn.cursor()
cursor.execute('''
SELECT ec.to_pfic, pf.name, pf.form_name, ec.method
FROM evolution_chains ec
JOIN pokemon_forms pf ON ec.to_pfic = pf.PFIC
WHERE ec.from_pfic = ?
''', (pfic,))
evolutions = cursor.fetchall()
return [{"to_pfic": to_pfic, "name": name, "form_name": form_name, "method": method} for to_pfic, name, form_name, method in evolutions]
def create_pokemon_widget(self, pfic, name, form_name):
widget = QWidget()
layout = QVBoxLayout()
widget.setLayout(layout)
image_path = f"images-new/{pfic}.png"
if os.path.exists(image_path):
pixmap = QPixmap(image_path)
image_label = QLabel()
image_label.setPixmap(pixmap.scaled(96, 96, Qt.KeepAspectRatio, Qt.SmoothTransformation))
layout.addWidget(image_label, alignment=Qt.AlignCenter)
name_label = QLabel(name)
name_label.setAlignment(Qt.AlignCenter)
layout.addWidget(name_label)
if form_name:
form_label = QLabel(form_name)
form_label.setAlignment(Qt.AlignCenter)
layout.addWidget(form_label)
return widget
class DatabaseVisualizer(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Pokémon Database Visualizer")
self.setGeometry(100, 100, 1200, 800)
self.conn = sqlite3.connect('pokemon_forms.db')
self.cursor = self.conn.cursor()
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.layout = QVBoxLayout()
self.central_widget.setLayout(self.layout)
self.tab_widget = QTabWidget()
self.layout.addWidget(self.tab_widget)
self.forms_tab = QWidget()
self.evolutions_tab = QWidget()
self.tab_widget.addTab(self.forms_tab, "Pokémon Forms")
self.tab_widget.addTab(self.evolutions_tab, "Evolution Chains")
self.setup_forms_tab()
self.setup_evolutions_tab()
def setup_forms_tab(self):
layout = QVBoxLayout()
self.forms_tab.setLayout(layout)
self.search_layout = QHBoxLayout()
self.search_label = QLabel("Search:")
self.search_input = QLineEdit()
self.search_button = QPushButton("Search")
self.search_button.clicked.connect(self.search_pokemon)
self.search_layout.addWidget(self.search_label)
self.search_layout.addWidget(self.search_input)
self.search_layout.addWidget(self.search_button)
layout.addLayout(self.search_layout)
self.table = QTableWidget()
layout.addWidget(self.table)
self.save_button = QPushButton("Save Changes")
self.save_button.clicked.connect(self.save_changes)
layout.addWidget(self.save_button)
self.load_forms_data()
def setup_evolutions_tab(self):
layout = QVBoxLayout()
self.evolutions_tab.setLayout(layout)
self.evolution_search_layout = QHBoxLayout()
self.evolution_search_label = QLabel("Search Pokémon:")
self.evolution_search_input = QLineEdit()
self.evolution_search_button = QPushButton("Search")
self.evolution_search_button.clicked.connect(self.search_evolution)
self.evolution_search_layout.addWidget(self.evolution_search_label)
self.evolution_search_layout.addWidget(self.evolution_search_input)
self.evolution_search_layout.addWidget(self.evolution_search_button)
layout.addLayout(self.evolution_search_layout)
self.evolution_scroll_area = QScrollArea()
self.evolution_scroll_area.setWidgetResizable(True)
layout.addWidget(self.evolution_scroll_area)
def load_forms_data(self):
self.cursor.execute('''
SELECT pf.PFIC, pf.name, pf.form_name, pf.national_dex, pf.generation, ps.storable_in_home
FROM pokemon_forms pf
LEFT JOIN pokemon_storage ps ON pf.PFIC = ps.PFIC
''')
data = self.cursor.fetchall()
self.table.setColumnCount(6)
self.table.setHorizontalHeaderLabels(["PFIC", "Name", "Form Name", "National Dex", "Generation", "Storable in Home"])
self.table.setRowCount(len(data))
for row, record in enumerate(data):
for col, value in enumerate(record):
item = QTableWidgetItem(str(value))
if col == 0: # PFIC column
item.setFlags(item.flags() & ~Qt.ItemIsEditable) # Make PFIC non-editable
self.table.setItem(row, col, item)
self.table.resizeColumnsToContents()
def search_pokemon(self):
search_term = self.search_input.text().lower()
for row in range(self.table.rowCount()):
match = False
for col in range(self.table.columnCount()):
item = self.table.item(row, col)
if item and search_term in item.text().lower():
match = True
break
self.table.setRowHidden(row, not match)
def save_changes(self):
try:
for row in range(self.table.rowCount()):
pfic = self.table.item(row, 0).text()
name = self.table.item(row, 1).text()
form_name = self.table.item(row, 2).text() or None
national_dex = int(self.table.item(row, 3).text())
generation = int(self.table.item(row, 4).text())
storable_in_home = self.table.item(row, 5).text().lower() == 'true'
self.cursor.execute('''
UPDATE pokemon_forms
SET name = ?, form_name = ?, national_dex = ?, generation = ?
WHERE PFIC = ?
''', (name, form_name, national_dex, generation, pfic))
self.cursor.execute('''
INSERT OR REPLACE INTO pokemon_storage (PFIC, storable_in_home)
VALUES (?, ?)
''', (pfic, storable_in_home))
self.conn.commit()
QMessageBox.information(self, "Success", "Changes saved successfully!")
except Exception as e:
QMessageBox.critical(self, "Error", f"An error occurred while saving changes: {str(e)}")
def search_evolution(self):
search_term = self.evolution_search_input.text().lower()
self.cursor.execute('''
SELECT DISTINCT name, PFIC
FROM pokemon_forms
WHERE LOWER(name) LIKE ?
''', (f'%{search_term}%',))
matching_pokemon = self.cursor.fetchall()
if matching_pokemon:
pokemon_name, pfic = matching_pokemon[0]
evolution_widget = PokemonEvolutionWidget(self.conn, pfic)
self.evolution_scroll_area.setWidget(evolution_widget)
else:
QMessageBox.information(self, "No Results", "No Pokémon found matching the search term.")
def closeEvent(self, event):
self.conn.close()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = DatabaseVisualizer()
window.show()
sys.exit(app.exec_())