import gi import os gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GObject from mods.db import Patient, store_patient_index, search_patients, db from datetime import date import peewee resource_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res') ui_dir = os.path.join(resource_dir, 'ui') main_win_file = os.path.join(ui_dir, 'main_win.glade') new_patient_win_file = os.path.join(ui_dir, 'new_patient_win.glade') builder = Gtk.Builder() class PatientFilter: def __init__(self): self.reset() def filter(self, query): if query != self.fstr: self.fstr = query self.ids = list(map(lambda x: x.id, search_patients(query))) return self.ids def reset(self): self.fstr = '' self.ids = [] patient_filter = PatientFilter() class PatientRow(Gtk.ListBoxRow): @GObject.Property def db_id(self): return self._db_id @db_id.setter def my_custom_property(self, value): self._db_id = value class MainWinHandler: def main_win_close(self, *args): Gtk.main_quit() def show_new_patient_win(self, button): new_patient_win = create_new_patient_win() new_patient_win.show_all() def patient_filter_changed(self, filter_widget): pl = builder.get_object('patient_list') pl.unselect_all() pl.invalidate_filter() '''pl = builder.get_object('patient_list') for r in pl.get_children(): pl.remove(r) fstr = builder.get_object('patient_filter').get_text().strip() if not fstr: for p in Patient.select(): pl.add(build_patient_row(p)) else: patients = search_patients(fstr) for p in patients: pl.add(build_patient_row(p)) pl.show_all()''' def build_patient_row(patient): row = PatientRow() row.props.db_id = patient.id label = Gtk.Label(f'{" ".join([patient.last_name, patient.first_name, patient.middle_name])}, {patient.birth_date}', xalign=0) row.add(label) return row def patient_sort_func(row1, row2, *a): text1 = row1.get_children()[0].get_text() text2 = row2.get_children()[0].get_text() return (text1 > text2) - (text1 < text2) def patient_filter_func(row): fstr = builder.get_object('patient_filter').get_text().strip() if not fstr: patient_filter.reset() return True return row.props.db_id in patient_filter.filter(fstr) builder.add_from_file(main_win_file) builder.connect_signals(MainWinHandler()) patient_list = builder.get_object('patient_list') patient_list.set_sort_func(patient_sort_func) patient_list.set_filter_func(patient_filter_func) with db.atomic(): for p in Patient.select(): patient_list.add(build_patient_row(p)) def show_msg(text, sec_text='', level='info'): msg_win_file = os.path.join(ui_dir, f'{level}_win.glade') b = Gtk.Builder() b.add_from_file(msg_win_file) w = b.get_object(level) w.set_property('text',text) w.set_property('secondary_text',sec_text) w.run() w.close() def create_new_patient_win(): b = Gtk.Builder() class NewPatienWinHandler: def only_digits(self, entry): text = entry.get_text() text = ''.join(filter(lambda x: x.isdigit(), text)) entry.set_text(text) def save_patient(self, *args): l_name = b.get_object('last_name').get_text().replace(' ', '') f_name = b.get_object('first_name').get_text().replace(' ', '') m_name = b.get_object('middle_name').get_text().replace(' ', '') if '' in (l_name, f_name): return show_msg('Не указаны имя или фамилия', 'Данные поля должны быть заполнены', level='warn') try: birth_d = int(b.get_object('birth_day').get_text()) if birth_d < 1 or birth_d > 31: return show_msg('Неверный день месяца', 'Укажите число в диапазоне 1-31', level='warn') birth_m = int(b.get_object('birth_month').get_text()) if birth_m < 1 or birth_m > 12: return show_msg('Неверный номер месяца', 'Укажите число в диапазоне 1-12', level='warn') birth_y = int(b.get_object('birth_year').get_text()) except ValueError: return show_msg('Неверно указана дата рождения', 'Все поля даты должны быть заполнены', level='warn') gender = b.get_object('gender').get_active_id() if not gender: return show_msg('Не выбран пол', level='warn') birth_date = date(birth_y, birth_m, birth_d) with db.atomic(): try: patient = Patient.create( last_name=l_name, first_name=f_name, middle_name=m_name, birth_date=birth_date, gender=gender ) except peewee.IntegrityError: return show_msg('Данный пациент уже существует', 'Пациент с указанными фамилией, именем\nи датой рождения уже есть с базе данных', level='warn') store_patient_index(patient) row = build_patient_row(patient) patient_list.add(row) patient_list.select_row(row) patient_list.show_all() b.get_object('new_patient_window').close() b.add_from_file(new_patient_win_file) b.connect_signals(NewPatienWinHandler()) w = b.get_object('new_patient_window') return w main_win = builder.get_object('main_window') main_win.show_all() Gtk.main()