고장 코드 테이블 이름 변경 및 관련 함수 수정: 'woojin200'에서 'fault_codes'로 변경, UI에서 고장 코드, 약어, 도면, 신호 목록을 위한 탭 추가 및 검색 기능 개선

This commit is contained in:
9700X_PC 2025-04-13 15:12:02 +09:00
parent b79692c16b
commit 391cb0dc7e
7 changed files with 709 additions and 175 deletions

74
app.py Normal file
View File

@ -0,0 +1,74 @@
import flet as ft
from database.db_manager import DatabaseManager
from ui.fault_finder import FaultFinderUI
def main(page: ft.Page):
"""
메인 애플리케이션 함수입니다.
Args:
page (ft.Page): Flet 페이지 객체
"""
# 페이지 설정
page.title = "고장 코드 검색 애플리케이션"
page.theme_mode = ft.ThemeMode.LIGHT
page.window_width = 1000
page.window_height = 800
page.window_min_width = 800
page.window_min_height = 600
page.padding = 10
page.bgcolor = ft.colors.WHITE
page.scroll = ft.ScrollMode.AUTO
# 데이터베이스 관리자 초기화
db_manager = DatabaseManager(db_path="fault_codes.db")
# UI 컴포넌트 초기화
fault_finder_ui = FaultFinderUI(page, db_manager)
# 앱 타이틀
app_title = ft.Container(
content=ft.Row([
ft.Icon(ft.icons.SEARCH, color=ft.colors.BLUE, size=32),
ft.Text("철도차량 고장코드 검색 시스템", size=24, weight=ft.FontWeight.BOLD),
], alignment=ft.MainAxisAlignment.CENTER),
margin=ft.margin.only(bottom=10),
padding=10,
bgcolor=ft.colors.BLUE_50,
border_radius=10,
)
# 메인 컨텐츠 영역
main_content = ft.Container(
content=fault_finder_ui.container,
expand=True,
bgcolor=ft.colors.WHITE,
border_radius=10,
border=ft.border.all(1, ft.colors.BLUE_200),
padding=10,
)
# 푸터
footer = ft.Container(
content=ft.Row([
ft.Text("© 2023 철도차량 정비 시스템", size=12, color=ft.colors.GREY_700),
ft.Text("버전 1.0", size=12, color=ft.colors.GREY_700),
], alignment=ft.MainAxisAlignment.SPACE_BETWEEN),
margin=ft.margin.only(top=10),
padding=10,
bgcolor=ft.colors.BLUE_50,
border_radius=10,
)
# 레이아웃 구성
page.add(
app_title,
main_content,
footer,
)
# 초기 데이터 로드
fault_finder_ui.load_all_codes()
if __name__ == "__main__":
ft.app(target=main)

163
create_additional_tables.py Normal file
View File

@ -0,0 +1,163 @@
import sqlite3
def create_abbreviation_table():
"""약어 테이블을 생성하고 샘플 데이터를 삽입합니다."""
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
# 테이블 생성
cursor.execute('''
CREATE TABLE IF NOT EXISTS abbreviations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
abbreviation TEXT NOT NULL,
description TEXT NOT NULL
)
''')
# 기존 데이터 삭제
cursor.execute("DELETE FROM abbreviations")
# 샘플 데이터 삽입
sample_data = [
('APS', '공기압력센서(Air Pressure Sensor)'),
('ATC', '자동 열차 제어(Automatic Train Control)'),
('ATP', '자동 열차 보호(Automatic Train Protection)'),
('ATO', '자동 열차 운행(Automatic Train Operation)'),
('BCP', '제동 제어 유닛(Brake Control Unit)'),
('CBC', '중앙 버퍼 커플러(Central Buffer Coupler)'),
('CCU', '중앙 제어 유닛(Central Control Unit)'),
('CCTV', '폐쇄회로 TV(Closed Circuit Television)'),
('CO', '컴프레서(Compressor)'),
('CPU', '중앙 처리 장치(Central Processing Unit)'),
('CU', '제어 유닛(Control Unit)'),
('DCDC', 'DC-DC 컨버터(DC-DC Converter)'),
('DI', '디지털 입력(Digital Input)'),
('DO', '디지털 출력(Digital Output)'),
('ELR', '전자식 부하 조절기(Electronic Load Regulator)'),
('ETCS', '유럽 열차 제어 시스템(European Train Control System)'),
('HVAC', '냉난방 장치(Heating, Ventilation, Air Conditioning)'),
('IPS', '무정전 전원 공급 장치(Interruption Power Supply)'),
('JRU', '법적 기록 장치(Juridical Recording Unit)'),
('LCD', '액정 디스플레이(Liquid Crystal Display)'),
('LED', '발광 다이오드(Light Emitting Diode)'),
('MU', '다중 장치(Multiple Unit)'),
('PCB', '인쇄 회로 기판(Printed Circuit Board)'),
('PIS', '승객 정보 시스템(Passenger Information System)'),
('SIV', '정지형 인버터(Static Inverter)'),
('TCMS', '열차 제어 관리 시스템(Train Control Management System)'),
('TFT', '박막 트랜지스터(Thin Film Transistor)'),
('VCB', '진공 차단기(Vacuum Circuit Breaker)')
]
cursor.executemany("INSERT INTO abbreviations (abbreviation, description) VALUES (?, ?)", sample_data)
conn.commit()
conn.close()
print("약어 테이블이 생성되었습니다.")
def create_drawing_table():
"""도면 테이블을 생성하고 샘플 데이터를 삽입합니다."""
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
# 테이블 생성
cursor.execute('''
CREATE TABLE IF NOT EXISTS drawings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
drawing_code TEXT NOT NULL,
drawing_name TEXT NOT NULL,
related_device TEXT,
drawing_path TEXT
)
''')
# 기존 데이터 삭제
cursor.execute("DELETE FROM drawings")
# 샘플 데이터 삽입
sample_data = [
('DRW-001', '주회로도', 'TCMS', None),
('DRW-002', '보조전원장치', 'SIV', None),
('DRW-003', '배터리 충전기', 'Battery Charger', None),
('DRW-004', '인버터 회로도', 'Inverter', None),
('DRW-005', '제동장치 회로도', 'Brake System', None),
('DRW-006', '공기압축기 회로도', 'Compressor', None),
('DRW-007', '자동문 제어 회로도', 'Door Control', None),
('DRW-008', '객실 공조장치', 'HVAC', None),
('DRW-009', '운전실 공조장치', 'Driver HVAC', None),
('DRW-010', '열차 정보 시스템', 'PIS', None),
('DRW-011', '승객 안내 시스템', 'PA System', None),
('DRW-012', '열차 방송 시스템', 'Broadcast System', None),
('DRW-013', '비상 인터폰', 'Emergency Interphone', None),
('DRW-014', '차량 연결 장치', 'Coupler System', None),
('DRW-015', '집전장치', 'Pantograph', None)
]
cursor.executemany("INSERT INTO drawings (drawing_code, drawing_name, related_device, drawing_path) VALUES (?, ?, ?, ?)", sample_data)
conn.commit()
conn.close()
print("도면 테이블이 생성되었습니다.")
def create_signal_table():
"""신호 테이블을 생성하고 샘플 데이터를 삽입합니다."""
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
# 테이블 생성
cursor.execute('''
CREATE TABLE IF NOT EXISTS signals (
id INTEGER PRIMARY KEY AUTOINCREMENT,
signal_code TEXT NOT NULL,
signal_name TEXT NOT NULL,
signal_type TEXT NOT NULL,
description TEXT,
source TEXT,
destination TEXT,
unit TEXT,
value_range TEXT
)
''')
# 기존 데이터 삭제
cursor.execute("DELETE FROM signals")
# 샘플 데이터 삽입
sample_data = [
('SIG001', '객실 온도', 'AI', '객실 내부 온도', 'HVAC 센서', 'TCMS', '°C', '-10~50'),
('SIG002', '운전실 온도', 'AI', '운전실 내부 온도', 'HVAC 센서', 'TCMS', '°C', '-10~50'),
('SIG003', '팬 속도', 'AI', '공조장치 팬 속도', 'HVAC 제어장치', 'TCMS', 'RPM', '0~2000'),
('SIG004', '문 열림 상태', 'DI', '객실문 열림/닫힘 상태', '문 제어장치', 'TCMS', 'Boolean', '0/1'),
('SIG005', '비상 브레이크', 'DI', '비상 제동 적용 여부', '제동 제어장치', 'TCMS', 'Boolean', '0/1'),
('SIG006', '팬토그래프 상태', 'DI', '팬토그래프 접촉 상태', '팬토그래프 제어장치', 'TCMS', 'Boolean', '0/1'),
('SIG007', '모터 전류', 'AI', '견인 모터 전류', '인버터', 'TCMS', 'A', '0~1000'),
('SIG008', '배터리 전압', 'AI', '배터리 전압', '배터리 관리 시스템', 'TCMS', 'V', '24~29'),
('SIG009', '냉각수 온도', 'AI', '견인 모터 냉각수 온도', '냉각 시스템', 'TCMS', '°C', '0~100'),
('SIG010', '차량 속도', 'AI', '차량 주행 속도', '속도 센서', 'TCMS', 'km/h', '0~120'),
('SIG011', '팬토그래프 압력', 'AI', '팬토그래프 공기압', '공기압 센서', 'TCMS', 'bar', '0~10'),
('SIG012', '주 공기통 압력', 'AI', '주 공기통 압력', '공기압 센서', 'TCMS', 'bar', '0~12'),
('SIG013', '보조 공기통 압력', 'AI', '보조 공기통 압력', '공기압 센서', 'TCMS', 'bar', '0~12'),
('SIG014', '제동 실린더 압력', 'AI', '제동 실린더 압력', '공기압 센서', 'TCMS', 'bar', '0~5'),
('SIG015', '비상 경보', 'DO', '비상 경보 상태', 'TCMS', '경보 장치', 'Boolean', '0/1'),
('SIG016', '객실 조명 상태', 'DO', '객실 조명 켜짐/꺼짐', 'TCMS', '조명 제어장치', 'Boolean', '0/1'),
('SIG017', '운전실 조명 상태', 'DO', '운전실 조명 켜짐/꺼짐', 'TCMS', '조명 제어장치', 'Boolean', '0/1'),
('SIG018', '외부 조명 상태', 'DO', '외부 조명 켜짐/꺼짐', 'TCMS', '조명 제어장치', 'Boolean', '0/1'),
('SIG019', '컴프레서 상태', 'DO', '컴프레서 동작 상태', 'TCMS', '컴프레서 제어장치', 'Boolean', '0/1'),
('SIG020', '견인 동력 설정', 'AO', '견인 동력 설정 값', 'TCMS', '인버터', '%', '0~100')
]
cursor.executemany("""
INSERT INTO signals (
signal_code, signal_name, signal_type, description,
source, destination, unit, value_range
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
""", sample_data)
conn.commit()
conn.close()
print("신호 테이블이 생성되었습니다.")
if __name__ == "__main__":
create_abbreviation_table()
create_drawing_table()
create_signal_table()

View File

@ -46,7 +46,7 @@ class DatabaseManager:
cursor.execute('''
SELECT fault_code, fault_name, fault_level, fault_type,
fault_detail, reaction, detect_condition, clear_condition, action
FROM woojin200
FROM fault_codes
WHERE fault_name LIKE ? OR fault_detail LIKE ?
ORDER BY fault_code
''', (f'%{search_term}%', f'%{search_term}%'))
@ -55,7 +55,7 @@ class DatabaseManager:
cursor.execute('''
SELECT fault_code, fault_name, fault_level, fault_type,
fault_detail, reaction, detect_condition, clear_condition, action
FROM woojin200
FROM fault_codes
ORDER BY fault_code
''')

View File

@ -4,14 +4,14 @@ import sqlite3
import uuid
def create_woojin200_table():
def create_fault_codes_table():
"""우진200 차량의 고장 코드 테이블을 생성합니다."""
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
# 우진200 테이블 생성
cursor.execute('''
CREATE TABLE IF NOT EXISTS woojin200 (
CREATE TABLE IF NOT EXISTS fault_codes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
code_id TEXT UNIQUE, -- UUID
fault_code TEXT, -- 고장코드
@ -90,7 +90,7 @@ def import_excel_to_sqlite():
conn = sqlite3.connect('fault_codes.db')
# 데이터프레임을 SQLite 테이블에 저장
df.to_sql('woojin200', conn, if_exists='replace', index=False)
df.to_sql('fault_codes', conn, if_exists='replace', index=False)
# 변경사항 저장 및 연결 종료
conn.commit()
@ -101,12 +101,12 @@ def import_excel_to_sqlite():
# 저장된 데이터 확인
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
cursor.execute("SELECT COUNT(*) FROM woojin200")
cursor.execute("SELECT COUNT(*) FROM fault_codes")
count = cursor.fetchone()[0]
print(f"{count}개의 레코드가 저장되었습니다.")
# 샘플 데이터 출력
cursor.execute("SELECT * FROM woojin200 LIMIT 5")
cursor.execute("SELECT * FROM fault_codes LIMIT 5")
sample_data = cursor.fetchall()
print("\n샘플 데이터:")
for row in sample_data:
@ -185,7 +185,7 @@ def import_excel_to_rotem200():
print(f"데이터베이스 오류: {str(e)}")
if __name__ == "__main__":
create_woojin200_table()
create_fault_codes_table()
create_rotem200_table()
import_excel_to_sqlite()
import_excel_to_rotem200()

Binary file not shown.

View File

@ -13,9 +13,9 @@ def main(page: ft.Page):
page.title = "고장코드 검색기"
page.theme_mode = ft.ThemeMode.LIGHT
page.padding = 20
page.window_width = 400 # 세로 모드에 맞는 너비
page.window_height = 800 # 세로 모드에 맞는 높이
page.window_resizable = False # 창 크기 고정
page.window_width = 1000 # 가로 모드에 맞게 너비 증가
page.window_height = 800 # 적절한 높이 유지
page.window_resizable = True # 창 크기 조절 가능하도록 변경
# 데이터베이스 매니저 초기화
db_manager = DatabaseManager()

View File

@ -16,38 +16,12 @@ class FaultFinderUI:
"""
self.page = page
self.db_manager = db_manager
# 상단 탭 버튼 그룹
self.tab_buttons = ft.Row([
ft.ElevatedButton("고장코드 목록", on_click=self._show_fault_codes, style=ft.ButtonStyle(bgcolor={"": ft.colors.BLUE_200})),
ft.ElevatedButton("약어 목록", on_click=self._show_abbreviations),
ft.ElevatedButton("도면 목록", on_click=self._show_drawings)
], spacing=10, alignment=ft.MainAxisAlignment.CENTER)
# 제작사와 장치분류를 나란히 배치
self.filter_row = ft.Row([
# 제작사 필터
ft.Container(
content=self.manufacturer_dropdown,
expand=True,
padding=10,
bgcolor=ft.colors.BLUE_GREY_50,
border_radius=10
),
# 장치분류 필터
ft.Container(
content=self.type_dropdown,
expand=True,
padding=10,
bgcolor=ft.colors.BLUE_GREY_50,
border_radius=10
)
], spacing=10)
self.current_view = "fault_code" # 현재 보기 모드 (fault_code, abbreviation, drawing, signal)
# 전체 제작사 목록 가져오기
self.manufacturers = self._get_manufacturers()
# 상단: 제작사 필터
# 최상단: 제작사 필터
self.manufacturer_dropdown = ft.Dropdown(
label="제작사 선택",
options=[
@ -60,7 +34,7 @@ class FaultFinderUI:
# 전체 고장 타입 목록 가져오기
self.fault_types = self._get_fault_types()
# 상단: 고장 타입 필터
# 고장 타입 필터
self.type_dropdown = ft.Dropdown(
label="장치분류 선택",
options=[
@ -70,7 +44,32 @@ class FaultFinderUI:
expand=True
)
# 중앙: 고장 리스트
# 뷰 전환 탭 (정비 자료)
self.view_tabs = ft.Tabs(
selected_index=0,
on_change=self._on_tabs_change,
tabs=[
ft.Tab(
text="고장코드",
icon=ft.icons.ERROR_OUTLINE
),
ft.Tab(
text="약어목록",
icon=ft.icons.MENU_BOOK
),
ft.Tab(
text="도면목록",
icon=ft.icons.DOCUMENT_SCANNER
),
ft.Tab(
text="신호목록",
icon=ft.icons.SIGNAL_CELLULAR_ALT
)
],
expand=True
)
# 고장 리스트
self.fault_list = ft.DataTable(
columns=[
ft.DataColumn(ft.Text("고장코드")),
@ -84,10 +83,54 @@ class FaultFinderUI:
horizontal_lines=ft.border.BorderSide(1, "grey")
)
# 약어 리스트
self.abbreviation_list = ft.DataTable(
columns=[
ft.DataColumn(ft.Text("약어")),
ft.DataColumn(ft.Text("용어설명"))
],
rows=[],
expand=True,
show_bottom_border=True,
column_spacing=10,
horizontal_lines=ft.border.BorderSide(1, "grey"),
visible=False
)
# 도면 리스트
self.drawing_list = ft.DataTable(
columns=[
ft.DataColumn(ft.Text("도면코드")),
ft.DataColumn(ft.Text("도면명")),
ft.DataColumn(ft.Text("관련장치"))
],
rows=[],
expand=True,
show_bottom_border=True,
column_spacing=10,
horizontal_lines=ft.border.BorderSide(1, "grey"),
visible=False
)
# 신호 리스트
self.signal_list = ft.DataTable(
columns=[
ft.DataColumn(ft.Text("신호코드")),
ft.DataColumn(ft.Text("신호명")),
ft.DataColumn(ft.Text("신호타입"))
],
rows=[],
expand=True,
show_bottom_border=True,
column_spacing=10,
horizontal_lines=ft.border.BorderSide(1, "grey"),
visible=False
)
# 중앙 리스트 컨테이너 (스크롤 가능하도록)
self.fault_list_container = ft.Container(
self.list_container = ft.Container(
content=ft.ListView(
controls=[self.fault_list],
controls=[self.fault_list, self.abbreviation_list, self.drawing_list, self.signal_list],
expand=True,
spacing=10,
padding=10,
@ -101,23 +144,49 @@ class FaultFinderUI:
# 하단: 검색 필드
self.search_field = ft.TextField(
label="검색어 입력",
hint_text="고장코드나 고장명을 입력하세요",
hint_text="검색어를 입력하세요",
expand=True,
on_change=self._on_search_change,
prefix_icon=ft.icons.SEARCH
)
# 메인 컨테이너 수정
# 메인 컨테이너
self.container = ft.Container(
content=ft.Column([
# 상단: 탭 버튼
self.tab_buttons,
# 최상단: 제작사 필터
ft.Container(
content=self.manufacturer_dropdown,
padding=10,
bgcolor=ft.colors.BLUE_GREY_50,
border_radius=10
),
# 제작사와 장치분류 필터
self.filter_row,
# 중간 상단: 뷰 전환 탭과 장치분류 나란히
ft.Row([
# 왼쪽: 뷰 전환 탭 (정비 자료)
ft.Container(
content=ft.Column([
ft.Text("정비 자료", weight=ft.FontWeight.BOLD, size=16),
self.view_tabs
]),
expand=6,
padding=5,
bgcolor=ft.colors.BLUE_GREY_50,
border_radius=10
),
# 오른쪽: 장치분류
ft.Container(
content=self.type_dropdown,
expand=4,
padding=5,
bgcolor=ft.colors.BLUE_GREY_50,
border_radius=10
),
]),
# 중앙: 고장 리스트
self.fault_list_container,
# 중앙: 리스트 (고장/약어/도면/신호)
self.list_container,
# 하단: 검색 필드
ft.Container(
@ -134,6 +203,50 @@ class FaultFinderUI:
# 초기 로딩
self.load_all_codes()
def _on_tabs_change(self, e):
"""
변경 호출되는 콜백 함수입니다.
Args:
e: 변경 이벤트
"""
index = self.view_tabs.selected_index
if index == 0:
self._switch_view("fault_code")
elif index == 1:
self._switch_view("abbreviation")
elif index == 2:
self._switch_view("drawing")
elif index == 3:
self._switch_view("signal")
def _switch_view(self, view_type):
"""
타입을 전환합니다 (고장코드/약어/도면/신호).
Args:
view_type (str): 변경할 타입 (fault_code, abbreviation, drawing, signal)
"""
self.current_view = view_type
# 해당 리스트만 보이도록 설정
self.fault_list.visible = (view_type == "fault_code")
self.abbreviation_list.visible = (view_type == "abbreviation")
self.drawing_list.visible = (view_type == "drawing")
self.signal_list.visible = (view_type == "signal")
# 해당 뷰에 맞는 데이터 로드
if view_type == "fault_code":
self.load_all_codes()
elif view_type == "abbreviation":
self.load_abbreviations()
elif view_type == "drawing":
self.load_drawings()
elif view_type == "signal":
self.load_signals()
self.page.update()
def _get_manufacturers(self) -> List[str]:
"""
제작사 목록을 가져옵니다.
@ -143,7 +256,7 @@ class FaultFinderUI:
"""
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
cursor.execute("SELECT DISTINCT manufacturers FROM woojin200 ORDER BY manufacturers")
cursor.execute("SELECT DISTINCT manufacturers FROM fault_codes ORDER BY manufacturers")
manufacturers = [manufacturer[0] for manufacturer in cursor.fetchall()]
conn.close()
return manufacturers
@ -157,7 +270,7 @@ class FaultFinderUI:
"""
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
cursor.execute("SELECT DISTINCT fault_type FROM woojin200 ORDER BY fault_type")
cursor.execute("SELECT DISTINCT fault_type FROM fault_codes ORDER BY fault_type")
types = [type_[0] for type_ in cursor.fetchall()]
conn.close()
return types
@ -168,13 +281,103 @@ class FaultFinderUI:
cursor = conn.cursor()
cursor.execute("""
SELECT fault_code, fault_name, fault_type
FROM woojin200
FROM fault_codes
ORDER BY fault_code
""")
results = cursor.fetchall()
conn.close()
self._update_fault_list(results)
def load_abbreviations(self):
"""약어 목록을 로드합니다."""
try:
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
cursor.execute("""
SELECT abbreviation, description
FROM abbreviations
ORDER BY abbreviation
""")
results = cursor.fetchall()
conn.close()
rows = []
for abbr, desc in results:
row = ft.DataRow(
cells=[
ft.DataCell(ft.Text(abbr)),
ft.DataCell(ft.Text(desc))
]
)
rows.append(row)
self.abbreviation_list.rows = rows
self.page.update()
except sqlite3.OperationalError:
# 테이블이 없는 경우
print("약어 테이블이 존재하지 않습니다.")
def load_drawings(self):
"""도면 목록을 로드합니다."""
try:
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
cursor.execute("""
SELECT drawing_code, drawing_name, related_device
FROM drawings
ORDER BY drawing_code
""")
results = cursor.fetchall()
conn.close()
rows = []
for code, name, device in results:
row = ft.DataRow(
cells=[
ft.DataCell(ft.Text(code)),
ft.DataCell(ft.Text(name)),
ft.DataCell(ft.Text(device))
]
)
rows.append(row)
self.drawing_list.rows = rows
self.page.update()
except sqlite3.OperationalError:
# 테이블이 없는 경우
print("도면 테이블이 존재하지 않습니다.")
def load_signals(self):
"""신호 목록을 로드합니다."""
try:
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
cursor.execute("""
SELECT signal_code, signal_name, signal_type
FROM signals
ORDER BY signal_code
""")
results = cursor.fetchall()
conn.close()
rows = []
for code, name, type_ in results:
row = ft.DataRow(
cells=[
ft.DataCell(ft.Text(code)),
ft.DataCell(ft.Text(name)),
ft.DataCell(ft.Text(type_))
],
on_select_changed=lambda e, code=code, name=name, type_=type_: self._show_signal_details(code, name, type_)
)
rows.append(row)
self.signal_list.rows = rows
self.page.update()
except sqlite3.OperationalError:
# 테이블이 없는 경우
print("신호 테이블이 존재하지 않습니다.")
def _on_manufacturer_change(self, e):
"""
@ -183,6 +386,9 @@ class FaultFinderUI:
Args:
e: 드롭다운 변경 이벤트
"""
if self.current_view != "fault_code":
return
selected_manufacturer = self.manufacturer_dropdown.value
selected_type = self.type_dropdown.value
@ -194,7 +400,7 @@ class FaultFinderUI:
if not selected_type:
cursor.execute("""
SELECT fault_code, fault_name, fault_type
FROM woojin200
FROM fault_codes
WHERE manufacturers = ?
ORDER BY fault_code
""", (selected_manufacturer,))
@ -202,7 +408,7 @@ class FaultFinderUI:
else:
cursor.execute("""
SELECT fault_code, fault_name, fault_type
FROM woojin200
FROM fault_codes
WHERE manufacturers = ? AND fault_type = ?
ORDER BY fault_code
""", (selected_manufacturer, selected_type))
@ -222,6 +428,9 @@ class FaultFinderUI:
Args:
e: 드롭다운 변경 이벤트
"""
if self.current_view != "fault_code":
return
selected_type = self.type_dropdown.value
selected_manufacturer = self.manufacturer_dropdown.value
@ -233,7 +442,7 @@ class FaultFinderUI:
if not selected_manufacturer:
cursor.execute("""
SELECT fault_code, fault_name, fault_type
FROM woojin200
FROM fault_codes
WHERE fault_type = ?
ORDER BY fault_code
""", (selected_type,))
@ -241,7 +450,7 @@ class FaultFinderUI:
else:
cursor.execute("""
SELECT fault_code, fault_name, fault_type
FROM woojin200
FROM fault_codes
WHERE fault_type = ? AND manufacturers = ?
ORDER BY fault_code
""", (selected_type, selected_manufacturer))
@ -262,42 +471,166 @@ class FaultFinderUI:
e: 검색 필드 변경 이벤트
"""
search_term = self.search_field.value
if not search_term:
if self.current_view == "fault_code":
self.load_all_codes()
elif self.current_view == "abbreviation":
self.load_abbreviations()
elif self.current_view == "drawing":
self.load_drawings()
elif self.current_view == "signal":
self.load_signals()
return
# 현재 뷰에 따라 다른 검색 실행
if self.current_view == "fault_code":
self._search_fault_codes(search_term)
elif self.current_view == "abbreviation":
self._search_abbreviations(search_term)
elif self.current_view == "drawing":
self._search_drawings(search_term)
elif self.current_view == "signal":
self._search_signals(search_term)
def _search_fault_codes(self, search_term):
"""
고장코드 검색을 실행합니다.
Args:
search_term (str): 검색어
"""
selected_type = self.type_dropdown.value
selected_manufacturer = self.manufacturer_dropdown.value
if search_term:
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
# 장치분류가 선택되지 않은 경우 전체 검색
if not selected_type:
cursor.execute("""
SELECT fault_code, fault_name, fault_type
FROM fault_codes
WHERE fault_code LIKE ? OR fault_name LIKE ?
ORDER BY fault_code
""", (f'%{search_term}%', f'%{search_term}%'))
# 장치분류가 선택된 경우 해당 분류 내에서 검색
else:
cursor.execute("""
SELECT fault_code, fault_name, fault_type
FROM fault_codes
WHERE fault_type = ? AND (fault_code LIKE ? OR fault_name LIKE ?)
ORDER BY fault_code
""", (selected_type, f'%{search_term}%', f'%{search_term}%'))
results = cursor.fetchall()
conn.close()
self._update_fault_list(results)
def _search_abbreviations(self, search_term):
"""
약어 검색을 실행합니다.
Args:
search_term (str): 검색어
"""
try:
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
# 장치분류가 선택되지 않은 경우 전체 검색
if not selected_type:
cursor.execute("""
SELECT fault_code, fault_name, fault_type
FROM woojin200
WHERE fault_code LIKE ? OR fault_name LIKE ?
ORDER BY fault_code
""", (f'%{search_term}%', f'%{search_term}%'))
# 장치분류가 선택된 경우 해당 분류 내에서 검색
else:
cursor.execute("""
SELECT fault_code, fault_name, fault_type
FROM woojin200
WHERE fault_type = ? AND (fault_code LIKE ? OR fault_name LIKE ?)
ORDER BY fault_code
""", (selected_type, f'%{search_term}%', f'%{search_term}%'))
cursor.execute("""
SELECT abbreviation, description
FROM abbreviations
WHERE abbreviation LIKE ? OR description LIKE ?
ORDER BY abbreviation
""", (f'%{search_term}%', f'%{search_term}%'))
results = cursor.fetchall()
conn.close()
self._update_fault_list(results)
else:
# 검색어가 없으면 현재 선택된 필터로 다시 로드
if selected_type:
self._on_type_change(e)
elif selected_manufacturer:
self._on_manufacturer_change(e)
else:
self.load_all_codes()
rows = []
for abbr, desc in results:
row = ft.DataRow(
cells=[
ft.DataCell(ft.Text(abbr)),
ft.DataCell(ft.Text(desc))
]
)
rows.append(row)
self.abbreviation_list.rows = rows
self.page.update()
except sqlite3.OperationalError:
print("약어 테이블이 존재하지 않습니다.")
def _search_drawings(self, search_term):
"""
도면 검색을 실행합니다.
Args:
search_term (str): 검색어
"""
try:
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
cursor.execute("""
SELECT drawing_code, drawing_name, related_device
FROM drawings
WHERE drawing_code LIKE ? OR drawing_name LIKE ? OR related_device LIKE ?
ORDER BY drawing_code
""", (f'%{search_term}%', f'%{search_term}%', f'%{search_term}%'))
results = cursor.fetchall()
conn.close()
rows = []
for code, name, device in results:
row = ft.DataRow(
cells=[
ft.DataCell(ft.Text(code)),
ft.DataCell(ft.Text(name)),
ft.DataCell(ft.Text(device))
]
)
rows.append(row)
self.drawing_list.rows = rows
self.page.update()
except sqlite3.OperationalError:
print("도면 테이블이 존재하지 않습니다.")
def _search_signals(self, search_term):
"""
신호 검색을 실행합니다.
Args:
search_term (str): 검색어
"""
try:
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
cursor.execute("""
SELECT signal_code, signal_name, signal_type
FROM signals
WHERE signal_code LIKE ? OR signal_name LIKE ? OR signal_type LIKE ?
ORDER BY signal_code
""", (f'%{search_term}%', f'%{search_term}%', f'%{search_term}%'))
results = cursor.fetchall()
conn.close()
rows = []
for code, name, type_ in results:
row = ft.DataRow(
cells=[
ft.DataCell(ft.Text(code)),
ft.DataCell(ft.Text(name)),
ft.DataCell(ft.Text(type_))
],
on_select_changed=lambda e, code=code, name=name, type_=type_: self._show_signal_details(code, name, type_)
)
rows.append(row)
self.signal_list.rows = rows
self.page.update()
except sqlite3.OperationalError:
print("신호 테이블이 존재하지 않습니다.")
def _update_fault_list(self, results):
"""
@ -334,7 +667,7 @@ class FaultFinderUI:
cursor = conn.cursor()
cursor.execute("""
SELECT fault_detail, reaction, detect_condition, clear_condition, action
FROM woojin200
FROM fault_codes
WHERE fault_code = ?
""", (code,))
details = cursor.fetchone()
@ -373,6 +706,58 @@ class FaultFinderUI:
dialog.open = True
self.page.update()
def _show_signal_details(self, code, name, type_):
"""
신호 상세 정보를 팝업으로 표시합니다.
Args:
code (str): 신호 코드
name (str): 신호명
type_ (str): 신호 타입
"""
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
cursor.execute("""
SELECT description, source, destination, unit, value_range
FROM signals
WHERE signal_code = ?
""", (code,))
details = cursor.fetchone()
conn.close()
if details:
description, source, destination, unit, value_range = details
# 상세 정보 다이얼로그 생성
dialog = ft.AlertDialog(
title=ft.Text(f"[{code}] {name}", weight=ft.FontWeight.BOLD),
content=ft.Column([
ft.Text("신호 타입: " + type_, color=ft.colors.BLUE_GREY_700),
ft.Divider(),
ft.Text("설명:", weight=ft.FontWeight.BOLD),
ft.Text(description, selectable=True),
ft.Divider(),
ft.Text("소스:", weight=ft.FontWeight.BOLD),
ft.Text(source, selectable=True),
ft.Divider(),
ft.Text("목적지:", weight=ft.FontWeight.BOLD),
ft.Text(destination, selectable=True),
ft.Divider(),
ft.Text("단위:", weight=ft.FontWeight.BOLD),
ft.Text(unit, selectable=True),
ft.Divider(),
ft.Text("값 범위:", weight=ft.FontWeight.BOLD),
ft.Text(value_range, selectable=True)
], width=500, height=500, scroll=ft.ScrollMode.AUTO),
actions=[
ft.TextButton("닫기", on_click=lambda e: self._close_dialog())
]
)
self.page.dialog = dialog
dialog.open = True
self.page.update()
def _close_dialog(self):
"""
다이얼로그를 닫는 메서드입니다.
@ -445,91 +830,3 @@ class FaultFinderUI:
expand=True,
)
])
def _show_fault_codes(self, e):
"""고장코드 목록을 표시합니다."""
self.load_all_codes()
self._update_tab_button_styles("고장코드 목록")
def _show_abbreviations(self, e):
"""약어 목록을 표시합니다."""
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
cursor.execute("""
SELECT abbreviation, full_name, description
FROM abbreviations
ORDER BY abbreviation
""")
results = cursor.fetchall()
conn.close()
# 약어 목록을 위한 새로운 데이터 테이블 생성
abbreviation_columns = [
ft.DataColumn(ft.Text("약어")),
ft.DataColumn(ft.Text("전체 이름")),
ft.DataColumn(ft.Text("설명"))
]
rows = []
for abbr, full_name, desc in results:
row = ft.DataRow(
cells=[
ft.DataCell(ft.Text(str(abbr))),
ft.DataCell(ft.Text(full_name)),
ft.DataCell(ft.Text(desc))
]
)
rows.append(row)
self.fault_list.columns = abbreviation_columns
self.fault_list.rows = rows
self.page.update()
self._update_tab_button_styles("약어 목록")
def _show_drawings(self, e):
"""도면 목록을 표시합니다."""
conn = sqlite3.connect('fault_codes.db')
cursor = conn.cursor()
cursor.execute("""
SELECT drawing_code, drawing_name, drawing_type, description
FROM drawings
ORDER BY drawing_code
""")
results = cursor.fetchall()
conn.close()
# 도면 목록을 위한 새로운 데이터 테이블 생성
drawing_columns = [
ft.DataColumn(ft.Text("도면 코드")),
ft.DataColumn(ft.Text("도면 이름")),
ft.DataColumn(ft.Text("도면 타입")),
ft.DataColumn(ft.Text("설명"))
]
rows = []
for code, name, type_, desc in results:
row = ft.DataRow(
cells=[
ft.DataCell(ft.Text(str(code))),
ft.DataCell(ft.Text(name)),
ft.DataCell(ft.Text(type_)),
ft.DataCell(ft.Text(desc))
]
)
rows.append(row)
self.fault_list.columns = drawing_columns
self.fault_list.rows = rows
self.page.update()
self._update_tab_button_styles("도면 목록")
def _update_tab_button_styles(self, active_tab):
"""탭 버튼의 스타일을 업데이트합니다."""
for button in self.tab_buttons.controls:
if button.text == active_tab:
button.style = ft.ButtonStyle(bgcolor={"": ft.colors.BLUE_200})
else:
button.style = ft.ButtonStyle(bgcolor={"": ft.colors.GREY_300})
self.page.update()