class AboutDialog(MDBoxLayout): about_dialog = None app = App.get_running_app() def __init__(self, **kwargs): super(MDBoxLayout, self).__init__(**kwargs) self.app = App.get_running_app() self.dismissed = False self.about_label = ObjectProperty() def about_menu(self): if not self.about_dialog: self.about_dialog = MDDialog( title=f"[color=%s]About this software[/color]" % get_hex_from_color(self.app.theme_cls.text_color), type="custom", content_cls=AboutContent(self), buttons=[ MDRaisedButton(text="CLOSE", text_color=self.app.theme_cls.primary_color, on_release=self.dismiss_dialog) ], size_hint_x=None, width=dp(850)) self.about_label.text = self.get_text() self.about_dialog.set_normal_height() self.about_dialog.open() @staticmethod def get_text(): with open("widgets/navdrawer/aboutmenu/about_dialog.txt", "r") as file: return file.read() def dismiss_dialog(self, *args): self.about_dialog.dismiss()
class Example(MDApp): dialog = None def build(self): return Builder.load_string(KV) def show_confirmation_dialog(self): if not self.dialog: self.dialog = MDDialog( title="Address:", type="custom", content_cls=Content(), buttons=[ MDFlatButton(text="CANCEL", text_color=self.theme_cls.primary_color, on_release=self.closeDialog), MDFlatButton(text="OK", text_color=self.theme_cls.primary_color, on_release=self.grabText), ], ) self.dialog.set_normal_height() self.dialog.open() def grabText(self, inst): for obj in self.dialog.content_cls.children: if isinstance(obj, MDTextField): print(obj.text) self.dialog.dismiss() def closeDialog(self, inst): self.dialog.dismiss()
class HospitalScreen(Screen): def add_hosp_list(self): if global_text == None: # add popup text to say "PLEASE SELECT A MEASURE" self.manager.current = 'search_screen' self.dialog = MDDialog(text='Please Select a Measure') self.dialog.set_normal_height() self.dialog.open() else: # get hospital compare data HCData.send_hc_request() hc_data = HCData.get_hc_data() self.ids.hosp_contain.clear_widgets() # refreshes list for hosp in hc_data: self.ids.hosp_contain.add_widget(ThreeLineListItem(text=hosp['hospital_name'], secondary_text=hosp['address'], tertiary_text='{}, {} {}'.format(\ hosp['city'], hosp['state'], hosp['zip_code']), on_release=self.switch_screen)) def switch_screen(self, list_item): hc_data = HCData.get_hc_data() # get model results data ModelData = GetModelData() ModelData.send_request() md_data = ModelData.req_data for hosp in hc_data: if hosp['hospital_name'] == list_item.text: found = False for result in md_data: if len(result['provider_id']) == 5: result['provider_id'] = '0' + str( result['provider_id']) if result['provider_id'] == str(hosp['provider_id']): found = True detail_text = list_item.text + \ '\n' + hosp['measure_id'] + ' Score = ' + hosp['score'] + ', ' + hosp['compared_to_national'] + \ '\n' + 'Prediction = ' + result['performance_class'] elif (hosp['hospital_name'] == list_item.text) & (~found): detail_text = list_item.text + '\n' + hosp[ 'measure_id'] + ' Score = ' + hosp[ 'score'] + ', ' + hosp['compared_to_national'] self.manager.current = 'detail_screen' self.manager.get_screen( 'detail_screen').ids.screen2_label.text = detail_text
class ReminderApp(MDApp): dialog = None def build(self): self.theme_cls.primary_palette="Amber" self.theme_cls.primary_hue ="400" screen=Builder.load_string(screen_helper) return screen def navigation_info(self): canbtn=MDFlatButton(text="Cancel",on_release=self.can_rem) self.dialog1=MDDialog(title='info',text='Part 1 of the whole REMNET project',size_hint=(0.7,1), buttons=[canbtn]) self.dialog1.open() def can_rem(self,obj): self.dialog1.dismiss() def add_task(self): if not self.dialog: self.dialog = MDDialog(title="Add reminder", size_hint=(0.7,1),type="custom",content_cls=Content(),buttons=[MDFlatButton(text="Cancel", on_release= self.close_dialog),MDRaisedButton(text="Add", on_release=self.time_picker),],) self.dialog.set_normal_height() self.dialog.open() def close_dialog(self,obj): self.dialog.dismiss() def time_picker(self,obj): from datetime import datetime previous_time = datetime.strptime("16:20:00", '%H:%M:%S').time() picker=MDTimePicker() picker.set_time(previous_time) picker.bind(time=self.got_time) picker.open() def got_time(self,picker_widget,the_time): self.dialog.dismiss() alarmhour=the_time.hour alarmmin=the_time.minute while True: if(alarmhour==datetime.datetime.now().hour and alarmmin==datetime.datetime.now().minute): for obj in self.dialog.content_cls.children: if isinstance(obj, MDTextField): toaster=win10toast.ToastNotifier() toaster.show_toast(obj.text, duration=10) break
class MeasureScreen(Screen): def add_meas_dialog(self): # popup to select measure measures = get_comp_measures().values() self.dialog = MDDialog( title='Measure', type='confirmation', items=[ItemConfirm(text=meas) for meas in measures], buttons=[ MDFlatButton(text='CANCEL', on_release=self.close_dialog), MDFlatButton(text='OK', on_release=self.update_meas_param) ]) self.dialog.set_normal_height() self.dialog.open() def update_meas_param(self, inst): # updates parameters based on add_meas_dialog() option HCData.update_hc_params({'measure_name': global_text}) self.dialog.dismiss() def close_dialog(self, inst): # closes popup, used when CANCEL button is pressed self.dialog.dismiss()
class Home(Screen): def on_enter(self, *args): if master: pass else: Clock.schedule_once(self.master_loc, .5) self.clear = False def load_entry_no(self, *args): if self.clear is True: lis = download(slave) self.ids.text.text = f"You have {len(lis)} entries" def loc(self, *args): self.dialog = MDDialog( title="Edit", text="HI Do you want to load or create a new file to save from?", buttons=[ MDFlatButton(text='New', on_press=self.new), MDFlatButton(text='Load', on_press=self.load), MDFlatButton(text='Cancel', on_press=self.close), ], ) self.dialog.set_normal_height() self.dialog.open() def master_loc(self, *args): self.dialog1 = MDDialog( title="Edit", text="HI please select the file you are using", buttons=[ MDFlatButton(text='Okay', on_press=self.load_master), ], ) self.dialog1.set_normal_height() self.dialog1.open() def load_master(self, *args): z = storagepath.get_documents_dir() m = filechooser.open_file() get_master(m) self.dialog1.dismiss() self.loc() def load(self, *args): self.close() self.location = filechooser.open_file() get_slave(self.location) def new(self, *args): self.close() layout = MDBoxLayout(orientation='vertical', spacing='12dp', size_hint_y=None, height="20dp") self.nam = MDTextField() layout.add_widget(self.nam) self.dialog = MDDialog( title="Edit", type='custom', content_cls=layout, buttons=[ MDFlatButton(text='Okay', on_press=self.ok), ], ) # self.dialog.set_normal_height() self.dialog.open() def ok(self, *args): if self.nam.text: s = self.nam.text.title() get_name(s) self.close() def close(self, *args): self.dialog.dismiss() self.dialog1.dismiss()
class LocationScreen(Screen): def add_hosp_dialog(self): # popup to enter hospital name self.dialog = MDDialog(title='Hospital', type='custom', content_cls=DialogContent(), buttons=[ MDFlatButton(text='CANCEL', on_release=self.close_dialog), MDFlatButton( text='OK', on_release=self.update_hosp_param) ]) self.dialog.set_normal_height() self.dialog.open() def add_state_dialog(self): # popup to select state code states = get_state_codes() self.dialog = MDDialog( title='State', type='confirmation', items=[ItemConfirm(text=state) for state in states], buttons=[ MDFlatButton(text='CANCEL', on_release=self.close_dialog), MDFlatButton(text='OK', on_release=self.update_state_param) ]) self.dialog.set_normal_height() self.dialog.open() def add_city_dialog(self): # popup to enter city name self.dialog = MDDialog(title='City', type='custom', content_cls=DialogContent(), buttons=[ MDFlatButton(text='CANCEL', on_release=self.close_dialog), MDFlatButton( text='OK', on_release=self.update_city_param) ]) self.dialog.set_normal_height() self.dialog.open() def add_zip_dialog(self): # popup to enter zip code self.dialog = MDDialog(title='Zip', type='custom', content_cls=DialogContent(), buttons=[ MDFlatButton(text='CANCEL', on_release=self.close_dialog), MDFlatButton( text='OK', on_release=self.update_zip_param) ]) self.dialog.set_normal_height() self.dialog.open() def grab_text(self, inst): # gets text from textbox in dialog popup for obj in self.dialog.content_cls.children: if isinstance(obj, MDTextField): return obj.text def update_hosp_param(self, inst): hosp_text = self.grab_text(inst).upper() HCData.update_hc_params({'hospital_name': hosp_text}) self.dialog.dismiss() def update_state_param(self, inst): # updates parameters based on add_state_dialog() option HCData.update_hc_params({'state': global_text}) self.dialog.dismiss() def update_city_param(self, inst): # updates parameters based on add_city_dialog() option city_text = self.grab_text(inst).upper() HCData.update_hc_params({'city': city_text}) self.dialog.dismiss() def update_zip_param(self, inst): # updates parameters based on add_zip_dialog() option zip_text = self.grab_text(inst) HCData.update_hc_params({'zip_code': zip_text}) self.dialog.dismiss() def close_dialog(self, inst): # closes popup, used when CANCEL button is pressed self.dialog.dismiss()
class ListScreen(Screen): lists = ObjectProperty(None) selected = [] selected_item = "" populate = False dialog = None def on_enter(self, *args): if self.lists and not self.populate: for item in self.lists: self.ids.list_content.add_widget( OneLineListItem(text=f"{item}", on_release=self.pressed)) self.populate = True def openNav(self): self.parent.master.ids.nav_drawer.set_state("open") self.parent.parent.ids.dialog = None def pressed(self, item): self.selected_item = item.text self.set_color_item(item) self.ids.upd_btn.disabled = False self.ids.del_btn.disabled = False def set_color_item(self, item): if len(self.selected) > 0: for i in self.selected: i.theme_text_color = 'Custom' i.text_color = (1, 1, 1, 1) self.selected.clear() item.theme_text_color = 'Custom' item.text_color = login_app.theme_cls.primary_color self.selected.append(item) def add_item(self): if self.ids.item_input.text: item = self.ids.item_input.text self.parent.master.acct.insert(self.name, item) # insert into db self.parent.master.acct.db.commit() self.ids.list_content.add_widget( OneLineListItem(text=f"{item}", on_release=self.pressed)) self.ids.item_input.text = "" else: login_app.show_toast("Field cannot be empty") def upd_item(self): if self.ids.item_input.text: item = self.ids.item_input.text self.parent.master.acct.update(self.name, self.selected[0].text, item) # update row in db self.parent.master.acct.db.commit() self.selected[0].text = item self.ids.item_input.text = "" self.ids.upd_btn.disabled = True self.ids.del_btn.disabled = True else: login_app.show_toast("Field cannot be empty") def del_item(self): self.parent.master.acct.delete(self.name, self.selected[0].text) # delete from db self.parent.master.acct.db.commit() self.ids.list_content.remove_widget(self.selected[0]) self.ids.del_btn.disabled = True self.ids.upd_btn.disabled = True def logout(self): self.parent.master.acct.db.commit() self.parent.master.acct.db.close() login_app.root.current = "Login" def show_alert_dialog(self): if not self.dialog: self.dialog = MDDialog( title="Delete List", text=f"Permanently delete {self.name} list", buttons=[ MDFlatButton(text="CANCEL", text_color=login_app.theme_cls.primary_color), MDFlatButton(text="OK", text_color=login_app.theme_cls.primary_color, on_release=self.delete_list), ], ) self.dialog.set_normal_height() self.dialog.open() def delete_list(self, inst): self.parent.master.ids.screen_man.current = "main" self.parent.master.acct.drop(self.name) self.parent.master.ids.content.ids.md_list.remove_widget( self.parent.master.ids.content.list_instance) self.parent.master.ids.screen_man.remove_widget(self) self.dialog.dismiss() self.dialog = None
class Home(ScreenManager): now_choose = StringProperty("未选择学习类别") # 当前的学习类别 total_num = NumericProperty(0) # 总的学习内容个数 has_study_num = NumericProperty(0) # 已经学习的内容个数 yesterday_num = NumericProperty(0) # 昨日学习个数 today_num = NumericProperty(0) # 今日学习个数 need_learn = NumericProperty(0) # 需要学习的个数 def __init__(self, **kwargs): super().__init__(**kwargs) appdata.IsInit() self.choose_category = (config_dict["choose_category"] if config_dict["choose_category"] else "未选择学习类别") self.ChangeCategory() # 构建弹窗 items = [] for category in config_dict["all_category"]: items.append( ItemConfirm( active=(category == config_dict["choose_category"]), text=category, on_release=self.CategorySelected, )) self.choose_category_dialog = MDDialog( size_hint=(0.9, None), title="选择学习类别", type="confirmation", items=items, buttons=[ MDFlatButton( text="取消", text_color=config.theme_cls.primary_color, on_release=lambda x: self.choose_category_dialog.dismiss(), ), MDFlatButton( text="确定", text_color=config.theme_cls.primary_color, on_release=lambda x: ( self.choose_category_dialog.dismiss(), self.ChangeCategory(), ), ), ], ) self.choose_category_dialog.set_normal_height() self.need_learn = (config_dict["max_learn"] - self.today_num if config_dict["max_learn"] - self.today_num > 0 else 0) self.GetSwitch() def SetValue(self, **kw): """ 说明: 界面接口,修改界面显示内容 args{ now_choose: 学习类别(标题) total_num: 总的学习内容个数 has_study_num: 已经学习的内容个数 yesterday_num: 昨日学习内容个数 today_num: 今日学习个数 } return: """ for key, value in kw.items(): if key == "now_choose": self.now_choose = value elif key == "total_num": self.total_num = value self.process_value = (self.has_study_num / self.total_num) * 100 elif key == "has_study_num": self.has_study_num = value self.process_value = (value / self.total_num) * 100 elif key == "yesterday_num": self.yesterday_num = value elif key == "today_num": self.today_num = value self.need_learn = (config_dict["max_learn"] - self.today_num if config_dict["max_learn"] - self.today_num > 0 else 0) def GetSwitch(self): # 构造轮播图内容 self.ids.switch.DeleteAll() max_table = len(config_dict["all_category"]) if max_table: self.contents = {} # 存储学习内容 used = [] for i in range(5): appdata.ChangeSheet( config_dict["all_category"][randint(0, max_table - 1)], ) content = appdata.MergeData(appdata.SelectIndex(), appdata.SelectRand(1)) if len(content): for index, c in content.items(): if c["内容"] not in used: widget = MyTwoLine(c) self.ids.switch.AddPage(c["内容"], widget) used.append(c["内容"]) else: widget = MDLabel(text="未选择学习类别", font_style="H6", halign="center") self.ids.switch.AddPage("未选择学习类别", widget) def ChanegCategory_DialogOpen(self): """ 说明: 打开选择学习类型的弹窗 args{ } return: """ self.choose_category_dialog.open() def CategorySelected(self, instance): """ 说明: 选择学习类别中列表条目响应事件 args{ } return: """ self.choose_category = instance.text print(self.choose_category) def ChangeCategory(self): """ 说明: 改变当前学习类别,将self.choose_category赋值给self.now_choose args{ } return: """ if self.choose_category: # 修改数据并保存 config_dict[ "choose_category"] = self.now_choose = self.choose_category config.SaveConfig() # --------------------------待完成 self.Refresh() def Refresh(self): yesterday = config.Yesterday() yesterday_num = record_dict[ yesterday] if yesterday in record_dict else 0 today = config.Today() today_num = record_dict[today] if today in record_dict else 0 if not appdata.ChangeSheet("user_" + self.now_choose): self.SetValue(yesterday_num=yesterday_num, today_num=today_num) return process = appdata.SelectIndex(2)[2:4] total_num, has_study_num = process total_num = int(total_num) has_study_num = int(has_study_num) if has_study_num > total_num: has_study_num = total_num self.SetValue(total_num=total_num, has_study_num=has_study_num, yesterday_num=yesterday_num, today_num=today_num)
class GoogleDriveExport: """ Main class for handling the export to google drive """ def __init__(self, parent_screen, export_filename, **kwargs): self.parent_screen = parent_screen self.export_filename = export_filename self.export_popup = None self.app = App.get_running_app() self.search_results = [] self.project_entries = [] self.root_projects = [] self.visited_projects = [] self.content = GoogleExportPopupContent(self) self.selected_folder = "root" @staticmethod def get_gdrive_service(): """ Gets the google drive service so we can upload to the users account Not completely sure how this works, treated as black box :return: object """ creds = None # The file token.pickle stores the user's access and refresh tokens, and is # created automatically when the authorization flow completes for the first # time. if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) # If there are no (valid) credentials available, let the user log in. if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # Save the credentials for the next run with open('token.pickle', 'wb') as token: pickle.dump(creds, token) # return Google Drive API service return build('drive', 'v3', credentials=creds) def search(self, query, content, first=True): """ Search for a given file/folder in the users drive based on query :param query: str :param content: object - popup content :param first: bool :return: None """ # search for the file service = self.get_gdrive_service() result = [] page_token = None while True: response = service.files().list( q=query, spaces="drive", fields="nextPageToken, files(id, name, mimeType, parents)", pageToken=page_token).execute() # iterate over filtered files for file in response.get("files", []): try: parent_id = file['parents'] except KeyError: parent_id = "N/A" result.append( (file["id"], file["name"], file["mimeType"], parent_id)) # print(type(list(file.keys())[-1])) page_token = response.get('nextPageToken', None) if not page_token: # no more files break self.search_results = result if first: self.update_projects_widget(content) self.root_projects = result return @mainthread def clear_projects(self): """Remove all project list items and add a spinner to signify loading""" self.content.projects_list.clear_widgets() self.content.spinner_container.add_widget( MDSpinner(size_hint=(None, None), pos_hint={ 'center_x': 0.5, 'center_y': 0.5 }, size=(dp(48), dp(48)))) @mainthread def update_projects_widget(self, *args): """Updates the layout for new projects after api call has finished""" self.content.spinner_container.clear_widgets() self.project_entries = [] for result in self.search_results: project_entry = GoogleProjectEntry(self) project_entry.text = result[1] self.project_entries.append(project_entry) self.content.projects_list.add_widget(project_entry) def fetch_search(self, content): """Start a new thread to search the users Google Drive and prevent blocking UI thread""" threading.Thread(target=self.search, args=( f"mimeType='application/vnd.google-apps.folder' " f"and trashed=false " f"and 'root' in parents", content, ), daemon=True).start() def open_export_popup(self): """ Opens the export popup and initiates a search for their projects, if no user signed in, search prompts a sign in :return: None """ self.fetch_search(self.content) if not self.export_popup: self.export_popup = MDDialog( title=f"[color=%s]Upload project to Google Drive[/color]" % get_hex_from_color(self.app.theme_cls.text_color), type="custom", content_cls=self.content, buttons=[ MDFlatButton(text="CANCEL", text_color=self.app.theme_cls.text_color, on_release=self.close_export_dialog), MDRaisedButton(text="UPLOAD", text_color=self.app.theme_cls.primary_color, on_release=self.start_upload_thread) ], size_hint=(None, None), size=(self.content.width + 50, self.content.height + 50)) self.export_popup.title = f"[color=%s]Upload project to Google Drive[/color]" % \ get_hex_from_color(self.app.theme_cls.text_color) self.export_popup.set_normal_height() self.export_popup.open() def start_upload_thread(self, *args): """Start the thread to upload project and prevent UI blocking""" threading.Thread(target=self.upload_project, daemon=True).start() def upload_project(self, *args): """Upload the users project to their google drive""" self.start_upload_ui() cwd = os.getcwd() # abs path of project project = os.path.abspath( utils.data[self.parent_screen.name]['proj_path']) files = [] for file in os.listdir(project): files.append(file) # send to zip file and save in temp so we can export to drive with ZipFile(f"temp/{self.export_filename}.zip", "w") as project_upload: os.chdir(project) for file in files: project_upload.write(file) os.chdir(cwd) folder_id = "root" if type( self.selected_folder) == str else self.selected_folder[0] file_metadata = { "name": f"{self.export_filename}.zip", "parents": [folder_id] } # upload project try: service = self.get_gdrive_service() media = MediaFileUpload(f"temp/{self.export_filename}.zip", resumable=True) service.files().create(body=file_metadata, media_body=media, fields='id').execute() self.prompt_success() # not sure what exceptions could be raised here except Exception: self.prompt_failure() return @mainthread def start_upload_ui(self): """Provides info to user that upload has started""" if type(self.selected_folder) == str: folder = "My Drive" else: folder = self.selected_folder[1] self.export_popup.dismiss() Snackbar(text=f"Starting upload of {self.export_filename}.zip to " f"{folder} in Google Drive").show() @mainthread def prompt_success(self): """Prompts the suer that their upload has succeeded""" if type(self.selected_folder) == str: folder = "My Drive" else: folder = self.selected_folder[1] Snackbar( text=f"{utils.data[self.parent_screen.name]['title']} exported" f" to {folder} in Google Drive as " f"{self.export_filename}.zip successfully").show() @mainthread def prompt_failure(self): """Prompts the suer that their upload has failed""" if type(self.selected_folder) == str: folder = "My Drive" else: folder = self.selected_folder[1] Snackbar( text= f"** Failed to export {utils.data[self.parent_screen.name]['title']} " f"to {folder} in Google Drive as " f"{self.export_filename}.zip **").show() def close_export_dialog(self, *args): """Close the export dialog""" self.export_popup.dismiss()
class SettingsContent(MDBoxLayout): appearance_dialog = None preferences_dialog = None app = App.get_running_app() def __init__(self, **kwargs): super(MDBoxLayout, self).__init__(**kwargs) self.app = App.get_running_app() self.appearance = self.app.theme_cls.primary_palette self.style = self.app.theme_cls.theme_style self.appearance_dismissed = False self.switch_active = True self.appearance_dialog = self.appearance_menu(False) def appearance_menu(self, open_dialog=True): if not self.appearance_dialog: if self.appearance_dismissed: self.appearance_dismissed = False self.appearance = self.app.theme_cls.primary_palette self.style = self.app.theme_cls.theme_style cancel_button = MDFlatButton( text="CANCEL", text_color=self.app.theme_cls.text_color, on_release=self.close_appearance_dialog) self.appearance_dialog = MDDialog( title=f"[color=%s]Change project appearance[/color]" % get_hex_from_color(self.app.theme_cls.text_color), type="custom", content_cls=AppearanceContent(cancel_button), buttons=[ cancel_button, MDRaisedButton(text="SAVE", text_color=self.app.theme_cls.primary_color, on_release=self.save_appearance) ]) if open_dialog: self.appearance_dialog.content_cls.active_theme = self.appearance self.appearance_dialog.buttons[ 0].text_color = self.app.theme_cls.text_color self.switch_active = self.appearance_dialog.content_cls.ids.style_switch.active self.appearance_dialog.bind( on_dismiss=self.close_appearance_dialog) self.appearance_dialog.set_normal_height() self.appearance_dialog.open() else: return self.appearance_dialog # called when dialog is dismissed and reverts to previous theme and style settings def close_appearance_dialog(self, *args): # to make sure we don't get infinite recursion if not self.appearance_dismissed: self.app.theme_cls.primary_palette = self.appearance self.app.theme_cls.theme_style = self.style self.appearance_dismissed = True self.appearance_dialog.dismiss() self.appearance_dialog.content_cls.ids.style_switch.active = self.switch_active # updating the bottom banner for layout in utils.bottom_banners: layout.md_bg_color = get_color_from_hex( colors[App.get_running_app().theme_cls.theme_style] ["CardsDialogs"]) # there is a chance that the file is no longer in the viewer widget try: for file in utils.files: file.color = App.get_running_app().theme_cls.text_color except ReferenceError: pass # for resetting the checkbox to the correct one on close for index, text in enumerate(utils.checkbox_text): if text == self.app.theme_cls.primary_palette: utils.theme_checkboxes[index].active = True else: utils.theme_checkboxes[index].active = False # allowing the dismiss call to be made again after the close has finished self.appearance_dismissed = False # saves the appearance, theme and style def save_appearance(self, *args): self.appearance = self.appearance_dialog.content_cls.active_theme self.style = self.appearance_dialog.content_cls.active_style utils.save_settings({ "theme": self.appearance_dialog.content_cls.active_theme, "style": self.appearance_dialog.content_cls.active_style }) self.app.theme_cls.primary_palette = self.appearance_dialog.content_cls.active_theme self.appearance_dismissed = True self.appearance_dialog.dismiss() self.appearance_dismissed = False def preferences_menu(self, open_dialog=True): if not self.preferences_dialog: content = PreferencesContent() cancel_button = MDFlatButton( text="CANCEL", text_color=self.app.theme_cls.text_color, on_release=self.close_preferences_dialog) self.preferences_dialog = MDDialog( title=f"[color=%s]Change app preferences[/color]" % get_hex_from_color(self.app.theme_cls.text_color), type="custom", content_cls=content, buttons=[ cancel_button, MDRaisedButton(text="SAVE", text_color=self.app.theme_cls.primary_color, on_release=self.save_preferences) ], size_hint=(None, None), size=content.size) self.preferences_dialog.title = f"[color=%s]Change app preferences[/color]" % \ get_hex_from_color(self.app.theme_cls.text_color) self.preferences_dialog.buttons[ 0].text_color = self.app.theme_cls.text_color self.preferences_dialog.set_normal_height() self.preferences_dialog.open() def close_preferences_dialog(self, *args): self.preferences_dialog.dismiss() def save_preferences(self, *args): # TODO update to utils.save_settings() utils.app_settings[ 'project_path'] = self.preferences_dialog.content_cls.project_path utils.app_settings[ 'default_export_path'] = self.preferences_dialog.content_cls.default_export_path utils.app_settings[ 'default_export_type'] = self.preferences_dialog.content_cls.default_export_type utils.save_settings(utils.app_settings) self.preferences_dialog.dismiss()
class IssueUploader(Screen): def on_enter(self, *args): self.inp = "" self.ids.matric_no.focus = True def back(self, *args): self.manager.transition.direction = 'down' self.manager.current = 'home' def check(self, targ): if targ != "": return True else: return False def repeat(self, target): target.focus = True def check_matric(self): if self.check(self.ids.matric_no.text) is True: self.ids.entry_lvl.focus = True else: self.warning_msg('Please input your Matric Number Thank you.') self.inp = 'matric' def check_entry_lvl(self): if self.check(self.ids.entry_lvl.text) is True: self.ids.dept_lvl.focus = True else: self.warning_msg('Please input your Entry Level Thank you.') self.inp = 'entry' def check_dept_lvl(self): if self.check(self.ids.dept_lvl.text) is True: self.ids.faculty.focus = True else: self.warning_msg('Please input your Department Level Thank you.') self.inp = 'lvl' def check_faculty(self): if self.check(self.ids.faculty.text) is True: self.ids.phone_no.focus = True else: self.warning_msg('Please input your Faculty Name Thank you.') self.inp = 'fac' def check_phone_no(self): if self.check(self.ids.phone_no.text) is True: self.ids.email.focus = True else: self.warning_msg('Please input your Phone Number Thank you.') self.inp = 'phone' def check_complaint(self): if self.check(self.ids.complaint.text) is True: pass else: self.warning_msg('Please input your Complaint Thank you.') self.ids.complaint.focus = True def check_mail(self): if self.check(self.ids.email.text) is True: self.ids.complaint.focus = True else: self.warning_msg('Please input your E-mail Thank you.') self.inp = 'mail' def submit(self): matric_no = self.ids.matric_no.text entry_lvl = self.ids.entry_lvl.text faculty = self.ids.faculty.text phone_no = self.ids.phone_no.text dept_lvl = self.ids.dept_lvl.text complain = self.ids.complaint.text mail = self.ids.email.text if matric_no and complain and mail: # server upload action no available self.save( 'Thank for contacting O.A.U portal response team, Your complaint will be solved within the next 48 hours.' ) self.ids.matric_no.text = "" self.ids.entry_lvl.text = "" self.ids.faculty.text = "" self.ids.phone_no.text = "" self.ids.dept_lvl.text = "" self.ids.complaint.text = "" self.ids.email.text = "" sql().upload_complaint(matric_no, entry_lvl, dept_lvl, faculty, phone_no, mail, complain, status="New") else: if matric_no == "": self.warning_msg("Please input your Full Name!") self.inp = 'matric' elif entry_lvl == "": self.warning_msg("Please input your Entry Level!") self.inp = 'entry' elif dept_lvl == "": self.warning_msg("Please input your Department Level!") self.inp = 'lvl' elif faculty == "": self.warning_msg("Please input your Faculty Name!") self.inp = 'fac' elif phone_no == "": self.warning_msg("Please input your Phone Number!") self.inp = 'phone' elif mail == "": self.warning_msg("Please input your E-mail!") self.inp = 'mail' elif complain == "": self.warning_msg("Please input your Complaint!") self.inp = 'comp' def warning_msg(self, text): self.dialog = MDDialog( title="Warning", text=text, buttons=[MDFlatButton( text='Okay', on_press=self.close, )], ) self.dialog.on_dismiss = self.cross_check self.dialog.set_normal_height() self.dialog.open() def save(self, text): self.dialog = MDDialog( title="Upload", text=text, buttons=[ MDFlatButton(text='Okay', on_release=self.back, on_press=self.close) ], ) self.dialog.set_normal_height() self.dialog.open() def cross_check(self, *args): if self.inp: if self.inp == 'matric': Clock.schedule_once(lambda x: self.repeat(self.ids.matric_no), .3) elif self.inp == "entry": Clock.schedule_once(lambda x: self.repeat(self.ids.entry_lvl), .3) elif self.inp == "lvl": Clock.schedule_once(lambda x: self.repeat(self.ids.dept_lvl), .3) elif self.inp == "fac": Clock.schedule_once(lambda x: self.repeat(self.ids.faculty), .3) elif self.inp == "phone": Clock.schedule_once(lambda x: self.repeat(self.ids.phone_no), .3) elif self.inp == "mail": Clock.schedule_once(lambda x: self.repeat(self.ids.email), .3) elif self.inp == "comp": Clock.schedule_once(lambda x: self.repeat(self.ids.complaint), .3) def close(self, *args): self.dialog.dismiss() def on_leave(self, *args): self.ids.matric_no.text = "" self.ids.entry_lvl.text = "" self.ids.faculty.text = "" self.ids.phone_no.text = "" self.ids.dept_lvl.text = "" self.ids.complaint.text = "" self.ids.email.text = ""
class Header(MDBoxLayout): """Header class for title and subtitle of each page""" title = ObjectProperty() subtitle = ObjectProperty() project_filename = ObjectProperty() dialog_title = None dialog_subtitle = None def __init__(self, parent_screen, **kwargs): """Init header""" super(MDBoxLayout, self).__init__(**kwargs) self.parent_screen = parent_screen self.app = App.get_running_app() self.data = parent_screen.page_data self.title.text = self.shorten_text(self.data["title"], 31) self.subtitle.text = self.shorten_text(self.data["subtitle"], 45) self.project_filename.text = f"Filename: {self.parent_screen.name}" # depends on grab_text_title() and close_dialog_title() methods as its binds def edit_title(self): """ Edit the title of the project, method called when the pencil next to the title is clicked :return: None """ # if this title dialog has not been created yet, create it. if not self.dialog_title: # Content class needs the hint text for the text field and the text to put into the text field, # in this case the project title self.dialog_title = MDDialog( title= f"[color=%s]Change project title, \nCurrent title: {self.data['title']}[/color]" % get_hex_from_color(self.app.theme_cls.text_color), type="custom", content_cls=HeaderPopupContent(new_hint_text="New title", new_text=self.data['title']), buttons=[ MDFlatButton(text="CANCEL", text_color=self.app.theme_cls.primary_color, on_release=self.close_dialog_title), MDRaisedButton(text="SAVE", text_color=self.app.theme_cls.primary_color, on_release=self.grab_text_title) ]) # adjust the size and open the dialog box self.dialog_title.set_normal_height() self.dialog_title.open() # depends on grab_text_subtitle() and close_dialog_subtitle() methods as its binds def edit_subtitle(self): """ Edit the subtitle of the project, method called when the pencil next to the subtitle is clicked :return: None """ # if subtitle dialog has not been created, create it if not self.dialog_subtitle: # Content class needs the hint text for the text field and the text to put into the text field, # in this case the project title self.dialog_subtitle = MDDialog( title= f"[color=%s]Change project subtitle, \nCurrent subtitle: {self.data['subtitle']}[/color]" % get_hex_from_color(self.app.theme_cls.text_color), type="custom", content_cls=HeaderPopupContent(new_hint_text="New subtitle", new_text=self.data['subtitle']), buttons=[ MDFlatButton(text="CANCEL", text_color=self.app.theme_cls.primary_color, on_release=self.close_dialog_subtitle), MDRaisedButton(text="SAVE", text_color=self.app.theme_cls.primary_color, on_release=self.grab_text_subtitle) ]) # adjust the size and open the dialog box self.dialog_subtitle.set_normal_height() self.dialog_subtitle.open() # to what was entered and shortens it if needed def grab_text_subtitle(self, inst): """ Grab the altered text from the edited subtitle, update and save that data method called when the save button is pressed, saves the subtitle text to project json key and sets the subtitle :param inst: button instance :return: None """ # this loops through all the children in the dialog_subtitle dialog box and if it is the text field, # set the subtitle to the shortened (if needed) text field text for obj in self.dialog_subtitle.content_cls.children: if isinstance(obj, MDTextField): if obj.text != "" and obj.text != self.subtitle.text: self.subtitle.text = self.shorten_text(obj.text, 45) self.data["subtitle"] = obj.text self.dialog_subtitle.title = f"[color=%s]Change project subtitle, Current subtitle: '{self.data['subtitle']}'" \ f"[/color]" % get_hex_from_color(App.get_running_app().theme_cls.text_color) self.dialog_subtitle.dismiss() # update data with new subtitle utils.save_project_data(self.data, f"{self.data['proj_path']}/project_data.json") utils.update_data() self.data = utils.data[self.parent_screen.name] def grab_text_title(self, inst): """ Grab the altered text from the edited title, update and save that data method called when the save button is pressed, saves the title text to project json key and sets the title :param inst: button instance :return: None """ # this loops through all the children in the dialog_title dialog box and if it is the text field, # set the title to the shortened (if needed) text field text for obj in self.dialog_title.content_cls.children: if isinstance(obj, MDTextField): if obj.text != "" and obj.text != self.title.text: self.title.text = self.shorten_text(obj.text, 31) self.data["title"] = obj.text self.dialog_title.title = f"[color=%s]Change project title, Current title: '{self.title.text}'[/color]" \ % get_hex_from_color(App.get_running_app().theme_cls.text_color) self.dialog_title.dismiss() # updates data with new title utils.save_project_data(self.data, f"{self.data['proj_path']}/project_data.json") utils.update_data() self.data = utils.data[self.parent_screen.name] # updates the title of the ProjectCard if the project cards name/project StringProperty match this page's parent # _screen's name for project_card in utils.project_cards: if project_card.project == self.parent_screen.name: project_card.home_project_title.text = project_card.home_page.shorten_title( self.title.text) # updates the project title for this project in the navigation drawer menu for project in utils.menu_projects: if project.next_win == self.parent_screen.name: utils.menu_projects[utils.menu_projects.index( project)].text = self.title.text def close_dialog_title(self, inst): """closes the edit title dialog box""" self.dialog_title.dismiss() def close_dialog_subtitle(self, inst): """closes the edit subtitle dialog box""" self.dialog_subtitle.dismiss() @staticmethod def shorten_text(text, length): """shortens given text to a given length if longer than length""" if len(text) >= length: return text[0:length] + "..." else: return text @staticmethod def get_lighter(color, percentage): """ Get a lighter shade of color, changed alpha value to do so used to get a lighter shade of a theme color :param color: list :param percentage: float :return: """ color[3] = percentage return color
class NoteItem(TwoLineListItem): dialog = None food_id = NumericProperty(None) food_name = StringProperty(None) def add_note_dialog(self): if not self.dialog: self.dialog = MDDialog( title=self.text, type='custom', content_cls=Content(), buttons=[ MDFlatButton( text='CANCEL', text_color=self.theme_cls.primary_color, on_release=self.my_callback ), MDFlatButton( text='ADD', text_color=self.theme_cls.primary_color, on_release=self.my_callback ) ], size_hint=[.8, 1], auto_dismiss=False ) self.dialog.set_normal_height() self.dialog.open() def view_note_dialog(self): if not self.dialog: self.dialog = MDDialog( title=self.text, text=self.secondary_text, buttons=[ MDFlatButton( text='CANCEL', text_color=self.theme_cls.primary_color, on_release=self.my_callback ), MDFlatButton( text='EDIT', text_color=self.theme_cls.primary_color, on_release=self.my_callback ) ], size_hint=[.8, .5], auto_dismiss=False ) self.dialog.open() def edit_note_dialog(self): if not self.dialog: self.dialog = MDDialog( title=self.text, type='custom', content_cls=Content(), buttons=[ MDFlatButton( text='CANCEL', text_color=self.theme_cls.primary_color, on_release=self.my_callback ), MDFlatButton( text='SAVE', text_color=self.theme_cls.primary_color, on_release=self.my_callback ) ], size_hint=[.8, 1], auto_dismiss=False ) self.dialog.content_cls.ids.note_text.text = self.secondary_text self.dialog.set_normal_height() self.dialog.open() def my_callback(self, popup_widget): app = MDApp.get_running_app() if popup_widget.text == 'EDIT': self.dialog.dismiss() self.dialog = None self.edit_note_dialog() elif popup_widget.text == 'ADD': query = 'UPDATE ingredients SET notes=? WHERE name1=? AND id=?;' vals = (self.dialog.content_cls.text, self.food_name, self.food_id) app.cursor.execute(query, vals) app.conn.commit() self.note_content = self.dialog.content_cls self.secondary_text = self.dialog.content_cls.text self.dialog.dismiss() self.dialog = None elif popup_widget.text == 'SAVE': query = 'UPDATE ingredients SET notes=? WHERE name1=? AND id=?;' vals = (self.dialog.content_cls.text, self.food_name, self.food_id) app.cursor.execute(query, vals) app.conn.commit() self.secondary_text = self.dialog.content_cls.text self.dialog.dismiss() self.dialog = None else: self.dialog.dismiss() self.dialog = None return popup_widget.text
class MainScreen(Screen): dialog = None def __init__(self, *args, **kwargs): super(MainScreen, self).__init__(*args, **kwargs) self.ids.uroki.text = '[color=0000ff]Уроки[/color]' self.ids.trenajor.text = '[color=0000ff]Тренажеры[/color]' self.ids.btvvod.text = 'Вводный урок' self.ids.urok1.text = 'Урок №1' self.ids.urok2.text = 'Урок №2' self.ids.urok3.text = 'Урок №3' self.ids.urok4.text = 'Урок №4' self.ids.urok5.text = 'Урок №5' self.ids.urok6.text = 'Урок №6' self.ids.urok7.text = 'Урок №7' self.ids.urok8.text = 'Урок №8' self.ids.urok9.text = 'Урок №9' self.ids.soroban.text = 'Соробан' self.ids.bn.text = 'Выход' self.ids.bn_clear.text = 'Сбросить прогресс' self.ids.tren_stolb.text = 'Столбцы' self.ids.tren_flesh.text = 'Флеш-карты' self.ids.tren_audio.text = 'Аудио-диктанты' def exit_func(self): print(Login.urok) conn = sqlite3.connect("Pupil.db") cur = conn.cursor() cur.execute( " UPDATE users SET count_lesson = ?, progress = ? WHERE id_users = ?", (Login.urok, Login.progress, Login.id)) conn.commit() conn.close() print(Login.progress) def show_alert_dialog(self): if not self.dialog: self.dialog = MDDialog( title="Предупреждение!", type="custom", text="Вы уверены, что хотите сбросить прогресс?", buttons=[ MDFlatButton(text="Сбросить", on_release=self.clearprogress), MDFlatButton(text="Отмена", on_release=self.closeDialog), ], ) self.dialog.set_normal_height() self.dialog.open() def clearprogress(self, inst): print("Сброс") Login.urok = 0 Login.progress = 0 conn = sqlite3.connect("Pupil.db") cur = conn.cursor() cur.execute( " UPDATE users SET count_lesson = ?, progress = ? WHERE id_users = ?", (Login.urok, Login.progress, Login.id)) conn.commit() conn.close() self.manager.get_screen( 'mainscreen').ids.urok_bd.text = 'Начните с Вводного урока' self.manager.get_screen( 'mainscreen' ).ids.progress_bd.text = 'Вы правильно выполнили 0 заданий' self.dialog.dismiss() def closeDialog(self, inst): self.dialog.dismiss()
class Entries(Screen): def on_enter(self, *args): if master: self.df = download(master[0]) else: self.master_loc() self.target = "" self.others = False self.target = "" self.others = False self.found = False def loc(self, *args): self.dialog = MDDialog( title="Edit", text="HI Do you want to load or create a new file to save from?", buttons=[ MDFlatButton(text='New', on_press=self.new), MDFlatButton(text='Load', on_press=self.load), MDFlatButton(text='Cancel', on_press=self.close), ], ) self.dialog.set_normal_height() self.dialog.open() def master_loc(self, *args): self.dialog1 = MDDialog( title="Edit", text="HI please select the file you are using", buttons=[ MDFlatButton(text='Okay', on_press=self.load_master), ], ) self.dialog1.set_normal_height() self.dialog1.open() def load_master(self, *args): z = storagepath.get_documents_dir() m = filechooser.open_file() get_master(m) self.df = download(master[0]) self.dialog1.dismiss() self.loc() def load(self, *args): self.close() self.location = filechooser.open_file() get_slave(self.location) def new(self, *args): self.close() layout = MDBoxLayout(orientation='vertical', spacing='12dp', size_hint_y=None, height="20dp") self.nam = MDTextField() layout.add_widget(self.nam) self.dialog = MDDialog( title="Edit", type='custom', content_cls=layout, buttons=[ MDFlatButton(text='Okay', on_press=self.ok), ], ) # self.dialog.set_normal_height() self.dialog.open() def ok(self, *args): if self.nam.text: s = self.nam.text.title() get_name(s) self.close() def check(self): for x in range(len(self.df)): if self.df[x]['REGNO'] == self.ids.reg_no.text: self.target = x self.found = True if self.found is False: self.warning = MDDialog(title="Warning", text="Registration Number Not Found", buttons=[MDFlatButton(text="CLose")]) self.warning.open() def issues(self): if self.others is False: frame = MDBoxLayout(orientation='vertical', size_hint_y=None, height=150) scroll = ScrollView() list_view = MDList() scroll.add_widget(list_view) remarks = [ 'Awaiting Result', 'Token not found', 'Passport Uploaded', 'Wrong result uploaded', 'No results uploaded', 'Card limit exceeded', 'Invalid card', 'Result not uploaded', 'Incomplete Result', 'Result not visible', 'Invalid pin', 'Invalid serial', 'Result checker has been used', 'Pin for Neco not given', 'Wrong result uploaded', 'Incomplete result', 'Token linked to another candidate', 'Others' ] for x in remarks: list_view.add_widget( OneLineListItem(text=x, on_press=self.get_selection)) self.chooser = MDDialog(title='Select Remark', size_hint=(.5, .4), type='custom', content_cls=frame) frame.add_widget(scroll) # self.chooser.set_normal_height() self.chooser.open() def get_selection(self, instance): if instance.text != 'Others': self.ids.remarks.text = instance.text else: self.others = True Clock.schedule_once(self.prompt, 0.1) self.chooser.dismiss() def prompt(self, *args): self.ids.remarks.focus = True self.ids.remarks.hint_text = "Type Issue here" def save(self): if self.ids.reg_no.text and self.ids.remarks.text: self.df[int(self.target)]['REMARK'] = self.ids.remarks.text if slave: if self.found: z = download(slave) self.go = True for v in z: if self.ids.reg_no.text in v['REGNO']: self.go = False break if self.go is True: z.append(self.df[int(self.target)]) upload_2(slave, z) elif name: f = storagepath.get_documents_dir() n = [] n.append(self.df[int(self.target)]) if os.path.exists(f"{f}/Helper Export/"): upload_1(f"{f}/Helper Export/{name}.xlsx", n) else: os.mkdir(f"{f}/Helper Export/") upload_1(f"{f}/Helper Export/{name}.xlsx", n) get_slave([f"{f}/Helper Export/{name}.xlsx"]) self.others = False self.ids.remarks.hint_text = "Select Remark" self.ids.reg_no.text = "" self.ids.remarks.text = "" else: self.warning = MDDialog(title="Warning", text="Please Fill All Values", buttons=[MDFlatButton(text="CLose")]) self.warning.open() def close(self, *args): self.dialog.dismiss() self.dialog1.dismiss()
class View(Screen): def on_enter(self, *args): self.reload() if slave: self.lis = download(slave) else: self.lis = [] def load(self): for x in range(len(self.lis)): items = ThreeLineListItem( text=f'No {x + 1}', secondary_text=f"REGNO: {self.lis[x]['REGNO']}", tertiary_text=f"Issue: {self.lis[x]['REMARK']}", on_release=self.target) self.ids.lister.add_widget(items) def target(self, instance): """Locates the index no in the list""" lis = self.lis for x in range(len(lis)): if lis[x]['REGNO'] == instance.secondary_text.lstrip( 'REGNO: '): self.edit() self.reg.text = lis[x]['REGNO'] self.issue.text = lis[x]['REMARK'] self.target_no = x def edit(self, *args): layout = MDBoxLayout(orientation='vertical', spacing='12dp', size_hint_y=None, height="120dp") self.reg = MDTextField() self.issue = MDTextField(multiline=True) layout.add_widget(self.reg) layout.add_widget(self.issue) self.dialog = MDDialog( title="Edit", type='custom', content_cls=layout, buttons=[ MDFlatButton(text='Save', on_press=self.save), MDFlatButton(text='Delete', on_press=self.delete_prompter), MDFlatButton(text='Cancel', on_press=self.close), ], ) self.dialog.set_normal_height() self.dialog.open() def save(self, *args): pass def saveR(self, *args): # a list for the values in the dialog box edit = [] # downloads the current excel file to lis # gets the values in the dialog box for obj in self.dialog.content_cls.children: if isinstance(obj, MDTextField): edit.append(obj.text) # changes the value of the current target to the new ones edited self.lis[int(self.target_no)]['REGNO'] = edit[1].upper() self.lis[int(self.target_no)]['REMARK'] = edit[0].title() upload_2(slave, self.lis) self.dialog.dismiss() self.reload() def close(self, *args): self.dialog.dismiss() def reload(self): """Refresh this page""" self.ids.lister.clear_widgets() self.lis = [] self.lis = download(slave) self.load() def delete_prompter(self, *args): """Prevents the user from accidentally deleting one of the list items""" text = f"Are you sure you want to delete the entry {self.lis[int(self.target_no)]['REGNO']} with the issue of " \ f"'{self.lis[int(self.target_no)]['REMARK']}'?" self.dialog.dismiss() self.warning(text) def delete(self, *args): # lis = download() self.lis.pop(int(self.target_no)) upload_2(slave, self.lis) self.dialog.dismiss() self.reload() def warning(self, text): self.dialog = MDDialog( title="Edit", text=text, buttons=[ MDFlatButton(text='Yes', on_press=self.delete), MDFlatButton(text='Cancel', on_press=self.close), ], ) self.dialog.set_normal_height() self.dialog.open()
class WalkApp(MDApp): dialog = None def build(self): self.theme_cls.primary_palette = 'Red' screen = Builder.load_string(navigation) return screen def radio_check(self, checkbox, value): if value: self.theme_cls.theme_style = 'Dark' else: self.theme_cls.theme_style = 'Light' def show_theme_picker(self): theme_dialog = MDThemePicker() theme_dialog.open() def show_datepicker(self): datepicker = MDDatePicker(callback=self.got_the_date) datepicker.open() def got_the_date(self, the_date): self.the_date = the_date def show_confirmation_dialog(self): if not self.dialog: cancel = MDFlatButton(text="CANCEL", text_color=self.theme_cls.primary_color, on_release=self.close_dialog) accept = MDFlatButton(text="ACCEPT", text_color=self.theme_cls.primary_color, on_release=self.close_dialog) self.result = accept self.dialog = MDDialog( title="Reset all data?", text="This action will delete all of your data.", size_hint = (0.7, 1), #auto_dismiss = False, buttons=[cancel, accept]) self.dialog.set_normal_height() self.dialog.open() def get_goal(self): goal = self.root.ids.set_goal.text goal_json = {"goal":[{"goal": goal}]} self.write_json(goal_json, 'goal.json') sleep(0.5) self.load() def show_snackbar(self, text): Snackbar(text=text).show() def show_popup(self, title, message): ok_button = MDFlatButton(text='Close', on_release=self.close_dialog) self.dialog = MDDialog(title=title, text=message, size_hint=(0.7, 1), buttons=[ok_button]) self.dialog.open() def get_new_record(self, file='data.json'): if self.root.ids.set_new_record.text == '': self.show_popup('Try again!', 'New Record Can Not Be Empty!') return new_data = { "new_record": self.root.ids.set_new_record.text, "the_date" : str(self.the_date), "location" : self.root.ids.set_location.text } if os.path.exists(file) == True: with open (file) as json_file: data = json.load(json_file) temp = data['NewRecord'] temp.append(new_data) self.write_json(data, 'data.json') self.root.ids.set_new_record.text = '' self.root.ids.set_location.text = '' self.show_snackbar("New Input Saved.") sleep(0.5) self.load() def write_json(self, data, file='data.json'): with open (file, 'w') as f: json.dump(data, f, indent=4) def reset_data(self): if os.path.exists('data.json'): os.remove('data.json') self.show_snackbar('Everything deleted!') self.load() else: self.show_snackbar('Something went wrong!') def play_video(self): source = 'data/video.mp4' return source def on_start(self): self.load() EventLoop.window.bind(on_keyboard=self.hook_keyboard) def hook_keyboard(self, window, key, *largs): if key == 27: #if self.current_screen.name == 'history' self.root.ids.screen_manager.current = 'Home' return True def close_dialog(self, obj): if obj.text == 'CANCEL': self.dialog.dismiss() elif obj.text == 'ACCEPT': self.dialog.dismiss() sleep(0.5) self.reset_data() else: pass def load(self): first_data = {"NewRecord":[ {"new_record": 0, "the_date": "", "location": ""}]} try: if os.path.exists('data.json') == False: self.write_json(first_data, 'data.json') with open ('goal.json') as json_file: goal_data = json.load(json_file) goal = goal_data['goal'][0]['goal'] self.root.ids.set_goal.text = goal with open ('data.json') as json_file: data = json.load(json_file) self.store = data['NewRecord'] new = [] if self.store[0]['new_record'] != '': for item in self.store: new.append(float(item['new_record'])) self.root.ids.completed.text = '[b]Completed: [/b]' + str(sum(new)) self.root.ids.remaining.text = '[b]Remaining: [/b]' + str(float(goal) - sum(new)) self.root.ids.max.text = '[b]Max: [/b]' + str(max(new)) mx = new.index(max(new)) max_date = self.store[mx]['the_date'] max_loc = self.store[mx]['location'] self.root.ids.max.secondary_text = 'Date: ' + str(max_date) self.root.ids.max.tertiary_text = 'Location: ' + str(max_loc) new.pop(0) self.root.ids.min.text = '[b]Min: [/b]' + str(min(new)) mn = new.index(min(new))+1 min_date = self.store[mn]['the_date'] min_loc = self.store[mn]['location'] self.root.ids.min.tertiary_text = 'Location: ' + str(min_loc) self.root.ids.min.secondary_text = 'Date: ' + str(min_date) if sum(new) >= float(goal): self.show_snackbar('Congratulations, goal accomplished :)') except: pass def history(self): self.root.ids.screen_manager.current = 'screen_5' # clear the previous lists from the screen self.root.ids.hist_id.clear_widgets() with open ('data.json') as json_file: data = json.load(json_file) data = data['NewRecord'] if len(data) > 1: data.pop(0) icon = 'data/history_2.png' for item in data: first = 'Distance: ' + str(item['new_record']) second = 'Date: ' + str(item['the_date']) third = 'Location: ' + str(item['location']) items = ThreeLineIconListItem(text=first, secondary_text=second, tertiary_text=third) items.add_widget(IconLeftWidget(icon=icon)) self.root.ids.hist_id.add_widget(items) def back(self): self.root.ids.screen_manager.current = 'Home'
class ExportPopup(MDBoxLayout): """ Majority of logic that handles exporting the project, the actual popup for the export button """ def __init__(self, parent_window, **kwargs): """Init the popup""" super(MDBoxLayout, self).__init__(**kwargs) self.app = App.get_running_app() self.export_path = 'Exports' # parent Window object (the screen which this export button lives in) self.parent_window = parent_window self.popup_content = ExportPopupContent(parent_window, self.parent_window.name) self.error_dialog = None self.error_noticed = False # Initialize the export dialog/popup window self.export_dialog = MDDialog( title= f"[color=%s]Export {utils.data[self.parent_window.name]['title']}?\n" f"[size=12]Exporting as {self.parent_window.name}[/size][/color]" % get_hex_from_color(self.app.theme_cls.text_color), type="custom", content_cls=self.popup_content, buttons=[ MDFlatButton(text="CANCEL", text_color=self.app.theme_cls.text_color, on_release=self.cancel_export), MDRaisedButton(text="EXPORT", text_color=self.app.theme_cls.primary_color, on_release=self.export_project) ], size_hint=(None, None), size=(self.popup_content.width + 50, self.popup_content.height + 50)) def open_export_menu(self, *args): """Opens the export popup""" self.export_dialog.set_normal_height() self.export_dialog.open() def cancel_export(self, *args): """Dismisses the export popup""" self.export_dialog.dismiss() def export_project(self, *args): """ Exports the project on the current window, 3 options for export: Folder - a folder which the project is exported to .zip file - a zip file the project is exported to Google Drive - uploads to the users google drive account, if the user has not selected an account, prompts them to select one :param args: button args :return: None """ # Path to the selected export folder in the popup dialog abs_export_path = os.path.abspath(self.popup_content.export_path) success = False if self.popup_content.export_type == "Folder": try: source_dir = os.path.abspath( utils.data[self.parent_window.name]['proj_path']) dest_dir = abs_export_path + "\\" + self.popup_content.export_filename shutil.copytree(source_dir, dest_dir) except FileExistsError: self.create_error_dialog( "This project already exists", f"\nThe directory [u]{abs_export_path}[/u] already has a folder named " f"[u]{self.parent_window.name}[/u]" f"\n\nPlease delete or move this folder to export this project to a folder" ) if not self.error_dialog: success = True else: success = False elif self.popup_content.export_type == ".zip File": files = [] project_path = os.path.abspath( utils.data[self.parent_window.name]['proj_path']) if os.path.isfile( f"{abs_export_path}\\{self.popup_content.export_filename}.zip" ) and not self.error_noticed: self.create_error_dialog( "This project zip file already exists", f"\nThe zip file will be overridden if you choose to export without moving the" f" current zip file in [u]{self.popup_content.export_path}[/u]" f"\n\nMove this file: [u]{self.popup_content.export_filename}.zip[/u]" ) # So the user has the option to override the zip file in the export directory if self.error_noticed: self.write_to_zip(files, project_path, abs_export_path, self.popup_content.export_filename) success = True else: self.write_to_zip(files, project_path, abs_export_path, self.popup_content.export_filename) success = True elif self.popup_content.export_type == "Google Drive": google_popup = GoogleDriveExport( self.parent_window, self.popup_content.export_filename) google_popup.open_export_popup() # Close the export popup because google_popup.open_export_popup() opens its own popup self.cancel_export() if success: self.export_dialog.dismiss() Snackbar( text=f"{utils.data[self.parent_window.name]['title']} exported" f" to {self.popup_content.export_path}\\{self.popup_content.export_filename} as " f"{self.popup_content.export_type} successfully").show() self.error_noticed = False def dismiss_error(self, *args): """Dismiss the error message and set noticed flag to True""" self.error_dialog.dismiss() self.error_dialog = None self.error_noticed = True def create_error_dialog(self, title, text): """ Creates an error dialog with title for the dialog title and text for the content of the message :param title: str :param text: str :return: None """ self.error_dialog = MDDialog(buttons=[ MDRaisedButton(text="CLOSE", text_color=self.app.theme_cls.text_color, on_release=self.dismiss_error) ]) self.error_dialog.title = f"[color=%s]{title}[/color]" % \ get_hex_from_color(self.app.theme_cls.text_color) self.error_dialog.text = text self.error_dialog.set_normal_height() self.error_dialog.open() @staticmethod def write_to_zip(files, project_path, abs_path, filename): """ Writes file to zip :param filename: what to name the file :param files: list :param project_path: str - path of the project to save :param abs_path: str - absolute path of export path :return: """ for file in os.listdir(project_path): files.append(f"{file}") cwd = os.getcwd() with ZipFile(f"{abs_path}\\{filename}.zip", 'w') as zip_file: os.chdir(project_path) for file in files: zip_file.write(file) os.chdir(cwd)
class NormalScreen(Screen): dialog = None global available_colors global selected_colors_list user = "" best_name = "" best_score = "" selected_colors_list = [] available_colors = [(0.0, 0.0, 1.0, 1.0), (1.0, 0.0, 0.0, 1.0), (1.0, 1.0, 0.0, 1.0), (0.0, 1.0, 0.0, 1.0), (1.0, 0.4, 0.8, 1.0), (0.9, 0.9, 0.9, 1.0)] def defaults(self): self.tries = 0 self.selected_colors_list = [ (0.0, 0.0, 1.0, 1.0), (1.0, 0.0, 0.0, 1.0), (1.0, 1.0, 0.0, 1.0), (0.0, 1.0, 0.0, 1.0) ] if os.path.isfile('prev_details.json'): with open('prev_details.json') as json_file: try: data = json.load(json_file) data = data['normal'] self.best_name = list(data.keys())[0] self.best_score = list(data.values())[0] except: self.best_name = "" self.best_score = "" self.ids.list_toolbar.title = f"Player: {self.user} Best Score: {self.best_score}({self.best_name})" self.game_colors = random.sample(available_colors, 4) # Colors to guess # print(self.game_colors) def on_enter(self, *args): self.defaults() def add_color(self, btn, text): switcher = { 'Blue': (0.0, 0.0, 1.0, 1.0), 'Red': (1.0, 0.0, 0.0, 1.0), 'Yellow': (1.0, 1.0, 0.0, 1.0), 'Green': (0.0, 1.0, 0.0, 1.0), 'Pink': (1.0, 0.4, 0.8, 1.0), 'Grey': (0.9, 0.9, 0.9, 1.0) } color = switcher.get(text) self.selected_colors_list[btn] = color def add_item(self): self.row = ProposedColors() self.ids.list_content.add_widget(self.row) self.row.ids['color1'].background_color = self.selected_colors_list[0] self.row.ids['color2'].background_color = self.selected_colors_list[1] self.row.ids['color3'].background_color = self.selected_colors_list[2] self.row.ids['color4'].background_color = self.selected_colors_list[3] self.output = [(0.6, 0.6, 0.6, 1.0), (0.6, 0.6, 0.6, 1.0), (0.6, 0.6, 0.6, 1.0), (0.6, 0.6, 0.6, 1.0)] n = 0 right_pos = 0 checked = [] for color in self.selected_colors_list: if checked.count(color) == 0: t = self.game_colors.count(color) n += t checked.append(color) for i in range(len(self.game_colors)): if self.selected_colors_list[i] == self.game_colors[i]: right_pos += 1 for j in range(n): self.output[j] = (1.0, 1.0, 1.0, 1.0) for k in range(right_pos): self.output[k] = (0.0, 0.0, 0.0, 1.0) checker = ProposedColors() self.ids.check_list.add_widget(checker) checker.ids['color1'].background_color = self.output[0] checker.ids['color1'].size = (20, 20) checker.ids['color2'].background_color = self.output[1] checker.ids['color2'].size = (20, 20) checker.ids['color3'].background_color = self.output[2] checker.ids['color3'].size = (20, 20) checker.ids['color4'].background_color = self.output[3] checker.ids['color4'].size = (20, 20) self.tries += 1 if self.selected_colors_list == self.game_colors: if self.best_score == "": self.best_score = 10 if self.tries < int(self.best_score): self.best_score = self.tries self.best_name = self.user self.save_score() self.show_alert_dialog( ' You won! Congratulations!!\n Play again??' ) if self.tries == 10: self.show_alert_dialog( ' Game Over!! Play again??') def play_again(self, e): self.ids.list_content.clear_widgets() self.ids.check_list.clear_widgets() self.defaults() self.dialog.dismiss() self.dialog = None def save_score(self): data = {self.user: self.best_score} scores['normal'] = data if os.path.isfile('prev_details.json'): with open('prev_details.json', 'w') as file: json.dump(scores, file) # file.write(self.user+"|"+str(self.best_score)) def logout(self, e): login_app.root.current = "Login" if self.dialog != None: self.dialog.dismiss() self.dialog = None self.ids.list_content.clear_widgets() self.ids.check_list.clear_widgets() def show_alert_dialog(self, txt): if not self.dialog: self.dialog = MDDialog( title="", text=txt, buttons=[ MDFlatButton(text="NO", text_color=login_app.theme_cls.primary_color, on_release=self.logout), MDFlatButton(text="OK", text_color=login_app.theme_cls.primary_color, on_release=self.play_again), ], ) self.dialog.set_normal_height() self.dialog.open()
class User(ScreenManager): color = StringProperty() accent_palette = StringProperty() radius = NumericProperty() refresh_home = None username = config_dict["username"] def __init__(self, **kwargs): super().__init__(**kwargs) self.username = config_dict["username"] self.snackbar = Snackbar(duration=1.5) # 提示窗 self.dialog = MDDialog( size_hint_x=0.8, text="确定清除全部由学习记录?", buttons=[ MDFlatButton( text="取消", text_color=config.theme_cls.primary_color, on_release=lambda x: (self.dialog.dismiss()), ), MDFlatButton( text="确定", text_color=config.theme_cls.primary_color, on_release=lambda x: ( self.ClearStudyProcess(), self.dialog.dismiss(), ), ), ], ) self.dialog.set_normal_height() self.studynum = StudyNum(max=999, min=5, step=5, now=config_dict["max_learn"]) self.study_num_dialog = MDDialog( size_hint_x=0.9, title="每日学习数量", type="custom", content_cls=self.studynum, buttons=[ MDFlatButton( text="取消", text_color=config.theme_cls.primary_color, on_release=lambda x: (self.study_num_dialog.dismiss()), ), MDFlatButton( text="确定", text_color=config.theme_cls.primary_color, on_release=lambda x: (self.ChangeStudyNum(), ), ), ], ) self.study_num_dialog.set_normal_height() self.difficulty = StudyNum(step=1, max=6, min=1, now=config_dict["difficulty"]) self.difficulty_dialog = MDDialog( size_hint_x=0.9, title="挑战难度", type="custom", content_cls=self.difficulty, buttons=[ MDFlatButton( text="取消", text_color=config.theme_cls.primary_color, on_release=lambda x: (self.difficulty_dialog.dismiss()), ), MDFlatButton( text="确定", text_color=config.theme_cls.primary_color, on_release=lambda x: (self.ChangeDifficulty(), ), ), ], ) self.difficulty_dialog.set_normal_height() """ self.theme_dialog = MDThemePicker() self.theme_dialog.ids.title.text = "主题颜色搭配" self.theme_dialog.ids.theme_tab.text = "主题色" self.theme_dialog.ids.accent_tab.text = "选中色" self.theme_dialog.ids.close_button.text = "保存" self.theme_dialog.ids.close_button.on_release = lambda :(self.theme_dialog.dismiss(), self.SaveThemeColor()) """ """ # 移除色调选择 self.theme_dialog.ids.tab_panel.tab_bar.layout.remove_widget( self.theme_dialog.ids.style_tab.tab_label ) self.theme_dialog.ids.tab_panel.carousel.remove_widget( self.theme_dialog.ids.style_tab ) """ def ChangeDifficulty(self): num = self.difficulty.num print("ChangeDifficulty", num) config_dict["difficulty"] = int(num) config.SaveConfig() self.difficulty_dialog.dismiss() self.snackbar.text = "修改挑战难度成功" self.snackbar.show() def ChangeStudyNum(self): text = self.studynum.num print("ChangeStudyNum", text) if text > 0: config_dict["max_learn"] = int(text) config.SaveConfig() self.refresh_home() self.study_num_dialog.dismiss() self.snackbar.text = "修改每日学习数量成功" self.snackbar.show() else: self.studynum.ids.input.hint_text = "每日学习个数必须大于0!" self.studynum.ids.input.text = "" self.studynum.ids.input.error = True """ def ChangeThemeColor(self): self.theme_dialog.open() """ def SaveThemeColor(self): #保存主题颜色设置 config_dict["theme_cls_primary_palette"] = self.color config_dict["theme_cls_accent_palette"] = self.accent_palette config.SaveConfig() def ClearStudyProcess(self): def __clear(): appdata.IsInit(True) config.record.clear() config.SaveRecord() self.snackbar.text = "清除成功" self.snackbar.show() threading.Thread(target=__clear).start()
class Chat(MDApp): dialog_1 = None dialog_2 = None chats = dict() nickname = 'Guest' length_chats = 0 press = 0 active_dialog = '' chat_id = 1 def build(self): self.theme_cls.accent_palette = "Lime" self.theme_cls.primary_palette = "LightBlue" return self.screen def on_start(self): ws.set_object_chats(self) thread.start_new_thread(lambda: ws.synch_all(self, self.pressed_btn), ()) for chat in db.get_chats(): self.chats[chat[0]] = chat[1] self.nickname = db.get_username() self.get_chats() if not db.get_username(): self.dialog_nickname() def check_and_start(self): if self.nickname != '': self.get_chats() def get_message(self, chat_name): for key, value in self.chats.items(): if chat_name == value: self.chat_id = key ws.set_id_button([key]) break self.root.ids.coc.clear_widgets() messages = db.get_messages(self.chat_id) for name in messages: self.root.ids.coc.add_widget( ThreeLineListItem(text=name[0], secondary_text=name[2], tertiary_text=name[1])) ws.set_id_button(self.chat_id) ws.synch_messages() def get_chats(self): # update_chats chat_name = db.get_chats() for i in range(self.length_chats, len(chat_name)): self.root.ids.box.add_widget( MDRectangleFlatButton( text=str(chat_name[i]), size_hint=(.1, None), on_release=self.pressed_btn, )) self.length_chats = len(chat_name) def pressed_btn(self, instance_toggle_button): self.active_dialog = instance_toggle_button.text self.get_message(self.active_dialog) def set_message(self): text_message = self.root.ids.message.text if text_message != '': today = datetime.today().strftime("%Y-%m-%d %H:%M:%S") db.set_message(text_message, today, self.chat_id, self.nickname) self.root.ids.message.text = "" ws.send_message(text_message, today, self.nickname, self.chat_id) def __init__(self, **kwargs): # создание меню super().__init__(**kwargs) self.screen = Builder.load_string(KV) def dialog_nickname(self): if not self.dialog_2: self.dialog_2 = MDDialog( title="Логин", type="custom", content_cls=Dialog(), buttons=[ MDFlatButton(text="Закрыть", text_color=self.theme_cls.primary_color, on_release=self.closeDialog), MDRaisedButton(text="Сохранить", text_color=self.theme_cls.primary_color, on_release=lambda x: self.grabText(inst=x)), ], ) self.dialog_2.set_normal_height() self.dialog_2.open() def grabText(self, inst): for obj in self.dialog_2.content_cls.children: if isinstance(obj, MDTextField): if obj.text != '': print(obj.text) db.set_username(obj.text) def closeDialog(self, inst): if self.dialog_2: self.dialog_2.dismiss() self.check_and_start() if self.dialog_1: self.dialog_1.dismiss()