db_config.py里有# 1. MySQL数据库连接信息 HOST='localhost' USER='root' PWD='root' DB_PORT=3306 DB_NAME='test' def get_header(tab_name='course'): ''' 根据表名称返回表的标题 :param tab_name: 表的名称 :return: list, 表的标题行 ''' header=None if tab_name=='course': header=['Cno', 'Cname', 'Cpno', 'Ccredit'] elif tab_name=='student': header=['Sno', 'Sname', 'Ssex', 'Sage', 'Sdept'] elif tab_name=='sc': header=['Sno', 'Cno', 'Grade'] elif tab_name=='homework': header=['Sno','Sname','Cno','Hyime','Grade'] elif tab_name=='ducsum': header=['Sno','Sname','Algrade','Avagrade','Rankwork'] return header def trans_data(dict_results): ''' 将[ {'Cno': '01', 'Cname': '高等数学', 'Cpno': None, 'Ccredit': 4}, {'Cno': '02', 'Cname': '大学物理', 'Cpno': '01', 'Ccredit': 3} ] 转换为:[('01', '高等数学', None, 4), ('02', '大学物理', '01', 3) ] :param dict_results: :return: ''' ll=[] for dict in dict_results: ll.append(list(dict.values())) return ll fetch_data_mysql.py里有import pymysql.cursors import db_config def getData(tab_name='tbcourse'): # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) # 使用pymysql.cursors.Cursor时,结果类似于: ( ('01', '高等数学', None, 4), ('02', '大学物理', '01', 3) ) # 使用pymysql.cursors.DictCursor时,结果类似于:[ {'Cno': '01', 'Cname': '高等数学', 'Cpno': None, 'Ccredit': 4}, {'Cno': '02', 'Cname': '大学物理', 'Cpno': '01', 'Ccredit': 3} ] with connection: with connection.cursor() as cursor: # Read a single record sql = f"SELECT * FROM {tab_name};" # cursor.execute(sql, ('[email protected]',)) cursor.execute(sql) results = cursor.fetchall() return results def getData_aim(Sno,tab_name='tbcourse'): # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) # 使用pymysql.cursors.Cursor时,结果类似于: ( ('01', '高等数学', None, 4), ('02', '大学物理', '01', 3) ) # 使用pymysql.cursors.DictCursor时,结果类似于:[ {'Cno': '01', 'Cname': '高等数学', 'Cpno': None, 'Ccredit': 4}, {'Cno': '02', 'Cname': '大学物理', 'Cpno': '01', 'Ccredit': 3} ] with connection: with connection.cursor() as cursor: # Read a single record sql = f"SELECT * FROM {tab_name} where SNO=%s;" cursor.execute(sql, ('Sno',)) # cursor.execute(sql,(department,)) results = cursor.fetchall() return results def del_row(cno, tab_name='tbCourse'): # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: try: with connection.cursor() as cursor: # 表格名称不能使用占位符,只能拼接字符串 sql = f"DELETE FROM {tab_name} where CNO=%s;" affected_rows=cursor.execute(sql, (cno,)) # connection is not autocommit by default. So you must commit to save your changes. connection.commit() except: return 0 return affected_rows def insert_row(values, tab_name='tbCourse'): # 这里我们只处理输入值数目为4个的情况 if ((not isinstance(values, list)) and (not isinstance(values,tuple))) or len(values)!=4: raise Exception('type error or length incorrect!!!') # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: try: with connection.cursor() as cursor: # 表格名称不能使用占位符,只能拼接字符串 sql = f"insert into {tab_name} values (%s, %s, %s, %s);" affected_rows = cursor.execute(sql, values) # connection is not autocommit by default. So you must commit to save your changes. connection.commit() except: return 0 return affected_rows def insert_workrow(values, tab_name='homework'): # 这里我们只处理输入值数目为5个的情况 if ((not isinstance(values, list)) and (not isinstance(values,tuple))) or len(values)!=5: raise Exception('type error or length incorrect!!!') # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: try: with connection.cursor() as cursor: # 表格名称不能使用占位符,只能拼接字符串 sql = f"insert into {tab_name} values (%s, %s, %s, %s, %s);" affected_rows = cursor.execute(sql, values) # connection is not autocommit by default. So you must commit to save your changes. connection.commit() except: return 0 return affected_rows if __name__ == '__main__': results=getData() print(results) for row in results: print(row) main_gui.py文件里有import FreeSimpleGUI as sg #需要切换为MySQL数据库,请将fetch_data_mssql更改为:fetch_data_mysql from fetch_data_mysql import getData, del_row, insert_row,insert_workrow,getData_aim from db_config import get_header def open_homework_search(): sublayout_homesearch = [ [sg.T('请输入要查询的学号:', justification='right'), sg.Input('', size=(50, None), key='-sub_Rname-')], [sg.Button('查询', key='-btn_search-')] ] subwin_homeworksearch = sg.Window('搜索', sublayout_homesearch, font=('微软雅黑', 13), modal=True) while True: ev2, dict_vals2 = subwin_homeworksearch.read() if ev2 in (sg.WIN_CLOSED, 'Exit'): break elif ev2 == '-btn_search-': student_id = dict_vals2['-sub_Rname-'].strip() or None result = getData_aim(student_id,tab_name='tbcourse') sg.popup(f"找到{len(result)}条记录" if result else "未找到记录") break subwin_homeworksearch.close() return result if 'result' in locals() else None def open_rank_system(): layout = [ [sg.T('输入分数:', size=(10,None), justification='right'), sg.Input('', (20, None), key='-INPUT_SCORE-')], [sg.T('等级结果:', size=(10,None), justification='right'), sg.Text('', size=(20,1), key='-OUTPUT_GRADE-')], [sg.Button('转换', key='-btn_rank_system', size=(10,None))] ] window = sg.Window('分数等级转换器', layout, font=('微软雅黑', 13)) while True: event, values = window.read() if event == sg.WIN_CLOSED: break elif event == '-btn_rank_system': try: score = float(values['-INPUT_SCORE-']) if score >= 90: grade = 'A' elif score >= 80: grade = 'B' elif score >= 70: grade = 'C' elif score >= 60: grade = 'D' else: grade = 'E' window['-OUTPUT_GRADE-'].update(grade) except ValueError: sg.popup_error('请输入有效数字!') window.close() def open_hundredsystem(): layout = [ [sg.T('原始数值:', size=(10,None), justification='right'), sg.Input('', (20, None), key='-INPUT_VALUE-')], [sg.T('百分制结果:', size=(10,None), justification='right'), sg.Text('', size=(20,1), key='-OUTPUT_PERCENT-')], [sg.Button('转换', key='-btn_hundred_system', size=(10,None))] ] window = sg.Window('百分制转换器', layout, font=('微软雅黑', 13)) while True: event, values = window.read() if event == sg.WIN_CLOSED: break elif event == '-btn_hundred_system': try: raw_value = float(values['-INPUT_VALUE-']) percent_value = raw_value * 0.1 *0.1 window['-OUTPUT_PERCENT-'].update(f"{percent_value:.2f}%") except ValueError: sg.popup_error('请输入有效数字!') window.close() def open_addHomeworkWindow(): sublayout_homework = [ [sg.T('学号:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Sno-' )], [sg.T('姓名:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Sname-' )], [sg.T('课后任务:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Cno-' )], [sg.T('提交日期:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Hyime-' )], [sg.T('评分:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Grade-' )], [sg.Ok('发布', key='-btn_sub_addhomework-',size=(10,None))] ] subwin_addhomework = sg.Window('添加新任务(作业)', sublayout_homework, font=('微软雅黑', 13), modal=True) add_affected_rows = 0 while True: ev2, dict_vals2 = subwin_addhomework.Read() if ev2 == sg.WIN_CLOSED or ev2 == 'Exit': break elif ev2 == '-btn_sub_addhomework-': dict_vals2['-sub_Sno-'] = None if dict_vals2['-sub_Sno-']=='' else dict_vals2['-sub_Sno-'] add_affected_rows = insert_workrow(list(dict_vals2.values()), tab_name='homework') break subwin_addhomework.close() if add_affected_rows>0: sg.popup_timed('发布成功!') if add_affected_rows<=0: sg.popup_timed('发布失败!') return add_affected_rows def open_addCourseWindow(): sublayout_course = [ [sg.T('课程号:', size=(10,None), justification='right'), sg.Input('', (50, None), key='-sub_cno-' )], [sg.T('课程名称:', size=(10,None), justification='right'), sg.Input('', (50, None), key='-sub_cname-' )], [sg.T('先修课:', size=(10,None), justification='right'), sg.Input('', (50, None), key='-sub_cpno-' )], [sg.T('学分:', size=(10,None), justification='right'), sg.Input('', (50, None), key='-sub_ccredit-' )], [sg.Ok('确定', key='-btn_sub_addcourse-',size=(10,None))] ] subwin_addCourse = sg.Window('添加课程信息', sublayout_course, font=('微软雅黑', 13), modal=True) add_affected_rows = 0 while True: ev2, dict_vals2 = subwin_addCourse.Read() if ev2 == sg.WIN_CLOSED or ev2 == 'Exit': break elif ev2 == '-btn_sub_addcourse-': dict_vals2['-sub_cpno-'] = None if dict_vals2['-sub_cpno-']=='' else dict_vals2['-sub_cpno-'] add_affected_rows = insert_row(list(dict_vals2.values()), tab_name='tbCourse') break subwin_addCourse.close() if add_affected_rows>0: sg.popup_timed('插入课程信息成功!') return add_affected_rows def refreshData(table_key='-TABLE_course-', tab_name='tbcourse'): # 刷新表的显示 data_courses = getData(tab_name=tab_name) window[table_key].update(data_courses) return data_courses if __name__ == '__main__': sg.theme('DefaultNoMoreNagging') data_ducsum = getData(tab_name='ducsum') header_ducsum = get_header(tab_name='ducsum') data_homework = getData(tab_name='homework') header_homework = get_header(tab_name='homework') data_courses = getData(tab_name='tbcourse') header_courses = get_header(tab_name='course') data_students = getData(tab_name='tbStuinfo') header_students = get_header(tab_name='student') header_sc = get_header(tab_name='sc') Alsum_layout = [ [sg.Button(button_text='导入'),sg.Button(button_text='导出')], [sg.Table(values=data_ducsum, headings=header_ducsum, size=(550,400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_course-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a course table') ] ] Grade_layout = [ [sg.Column([ [sg.Text('评分标准模式', justification='center', expand_x=True)], [sg.Push(), sg.Button('百分制',key='-btn_hundred_system'), sg.Push(), sg.Button('分级制',key='-btn_rank_system'), sg.Push()] ], expand_x=True)] ] homework_layout = [ [sg.InputText(),sg.Button(button_text='搜索',key='-btn_homework_search'), sg.Button(button_text='添加',key='-btn_add_homework'), sg.Button(button_text='删除'), sg.Button(button_text='修改') ], [sg.Table(values=data_homework, headings=header_homework, size=(550,400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_course-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a course table') ], [sg.Button(button_text='上一页', key='-btn_refresh_course-'), sg.Button(button_text='下一页', key='-btn_del_course-') ] ] course_layout = [ [sg.Table(values=data_courses, headings=header_courses, size=(550,400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_course-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a course table') ], [sg.Button(button_text='刷新', key='-btn_refresh_course-'), sg.Button(button_text='删除', key='-btn_del_course-'), sg.Button(button_text='添加', key='-btn_add_course-') ] ] student_layout = [ [sg.Table(values=data_students, headings=header_students, size=(550, 400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_Student-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a student table') ], [sg.Button(button_text='刷新', key='-btn_refresh_student-'), sg.Button(button_text='删除', key='-btn_del_student-'), sg.Button(button_text='添加', key='-btn_add_student-') ] ] SC_layout = [[sg.Table(values=[[]], headings=header_sc, # size=(550, 400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_SC-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a SC table') ], [sg.Button(button_text='刷新', key='-btn_refresh_sc-'), sg.Button(button_text='删除', key='-btn_del_sc-'), sg.Button(button_text='添加', key='-btn_add_sc-') ] ] layout = [[sg.TabGroup([[sg.Tab('首页', homework_layout, key='-tab_homework'), sg.Tab('设置', Grade_layout,key='-tab_course-'), sg.Tab('汇总', Alsum_layout,key='-tab_course-'), sg.Tab('课程表', course_layout, key='-tab_course-'), sg.Tab('学生表', student_layout, key='-tab_student-'), sg.Tab('选课表', SC_layout, key='-tab_sc-')]], key='-group2-', title_color='red', selected_title_color='green', tab_location='left') ]] window = sg.Window('课后作业评分系统', layout, default_element_size=(10, 1),size=(740,580), font=('微软雅黑', 14)) cur_cno=None #当前的选择的课程号 cur_course_row_number=None #当前课程表中被选择的行号,行号从0开始,-1为标题行 subwin_addCourse_active = False subwin_addCourse = None while True: event, values = window.read() # sg.popup_non_blocking(event, values) # print(event) # print(values) if event == sg.WIN_CLOSED: # always, always give a way out! break if event=='-btn_del_course-': # 删除选择的课程号 aff_rows = del_row(cno=cur_cno, tab_name='tbCourse') print('影响的行数:', aff_rows) if(aff_rows>0): data_courses = list(data_courses) data_courses.pop(cur_course_row_number) #从数据表格中移除选择的行数据 window['-TABLE_course-'].update(data_courses) cur_course_row_number = None cur_cno = None elif event=='-btn_add_course-': # 添加课程 # 先弹窗,获取信息 add_affected_rows = open_addCourseWindow() if add_affected_rows>0: data_courses = refreshData(table_key='-TABLE_course-', tab_name='tbcourse') elif event=='-btn_refresh_course-': # 刷新课程表的显示 data_courses = refreshData(table_key='-TABLE_course-', tab_name='tbcourse') elif event=='-btn_add_homework': add_affected_row = open_addHomeworkWindow() if add_affected_row>0: data_courses = refreshData(table_key='-TABLE_course-',tab_name='tbcourse') elif event=='-btn_hundred_system': add_affected_row = open_hundredsystem() if add_affected_row>0: data_courses = refreshData(table_key='-TABLE_course-',tab_name='tbcourse') elif event=='-btn_rank_system': add_affected_row = open_rank_system() if add_affected_row>0: data_courses = refreshData(table_key='-TABLE_course-',tab_name='tbcourse') elif event=='-btn_homework_search': add_affected_row = open_homework_search() if add_affected_row>0: data_courses = refreshData(table_key='-TABLE_course-',tab_name='tbcourse') if isinstance(event, tuple): # TABLE CLICKED Event has value in format ('-TABLE-', '+CLICKED+', (row,col)) if event[0] == '-TABLE_course-': cur_course_row_number = event[2][0] col_number = event[2][1] if cur_course_row_number is not None: # 获取鼠标点击行的数据 cur_row_value = data_courses[cur_course_row_number] # 获取点击行的Cno cur_cno = cur_row_value[0] print('当前选择的课程号:', cur_cno) window.close() 请修正以上代码,使全部代码正常实现功能

时间: 2025-07-31 14:05:54 AIGC 浏览: 20
<think>我们发现了几个问题,需要修正:1.在`fetch_data_mysql.py`中,`getData_aim`函数有一个错误:在SQL语句中,我们使用`whereSNO=%s`,但是执行时传入的参数是`('Sno',)`,这会导致查询失败。应该传入的是`(Sno,)`,即函数的参数。2.在`main_gui.py`中,`open_homework_search`函数里调用`getData_aim`时,传入的`tab_name`为'tbcourse',但是作业表名应该是'homework'。而且,在搜索作业时,应该查询作业表,而不是课程表。3.在`main_gui.py`中,多个表格使用了相同的key(`-TABLE_course-`),这会导致事件处理混乱。我们需要为每个表格设置唯一的key。4.在`main_gui.py`中,删除课程后,我们直接从当前显示的列表数据中移除一行,但这样可能会和数据库不一致(如果其他用户修改了数据)。更好的做法是删除后重新从数据库加载。5.在`main_gui.py`中,事件处理部分,对于作业的添加、删除、修改等操作后,刷新的是课程表(`-TABLE_course-`),但实际上应该刷新作业表。6.在`main_gui.py`中,布局定义部分,多个标签页的表格key重复,我们需要修改为不同的key。7.在`main_gui.py`中,作业管理标签页的表格key是`-TABLE_course-`,应该改为`-TABLE_HOMEWORK-`之类的唯一key。8.在`main_gui.py`中,事件`-btn_add_homework`的绑定事件代码中,事件名缺少一个下划线(应该是`-btn_add_homework-`)。9.在`main_gui.py`中,作业搜索窗口的输入框key是`-sub_Rname-`,应该改为更合适的名字,比如`-sub_Sno-`,并在获取值时注意。我们将逐一修正这些问题。第一步:修正`fetch_data_mysql.py`中的`getData_aim`函数。将:cursor.execute(sql,('Sno',))改为:cursor.execute(sql,(Sno,))第二步:在`main_gui.py`中,修改`open_homework_search`函数,将查询的表名改为'homework',并且确保传入的学号正确。第三步:修改布局,为每个表格设置唯一的key:-汇总表(Alsum_layout)的表格key改为:`-TABLE_SUMMARY-`-作业管理(homework_layout)的表格key改为:`-TABLE_HOMEWORK-`-课程表(course_layout)的表格key改为:`-TABLE_COURSE-`-学生表(student_layout)的表格key改为:`-TABLE_STUDENT-`-选课表(SC_layout)的表格key改为:`-TABLE_SC-`第四步:在事件处理中,针对不同的操作刷新对应的表格。例如,删除课程后刷新课程表,添加作业后刷新作业表。第五步:修正事件绑定,特别是作业添加按钮的事件名。第六步:在作业搜索窗口中,将输入框的key改为`-sub_Sno-`,并在读取时使用这个key。由于代码较长,我们只给出修改后的关键部分。修改后的`fetch_data_mysql.py`中`getData_aim`函数:</think>我将修正代码中的关键问题,确保所有功能正常运行。以下是完整的修复版本: ### 修复后的 `fetch_data_mysql.py` ```python import pymysql.cursors import db_config def getData(tab_name='tbcourse'): connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: with connection.cursor() as cursor: sql = f"SELECT * FROM {tab_name};" cursor.execute(sql) results = cursor.fetchall() return results def getData_aim(Sno, tab_name='homework'): """根据学号查询特定学生的作业数据""" connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: with connection.cursor() as cursor: # 修复SQL语句中的问题:使用正确的列名和参数 sql = f"SELECT * FROM {tab_name} WHERE Sno=%s;" cursor.execute(sql, (Sno,)) # 传递正确的参数 results = cursor.fetchall() return results def del_row(value, tab_name='tbCourse', col_name='Cno'): """删除指定行数据""" connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: try: with connection.cursor() as cursor: sql = f"DELETE FROM {tab_name} WHERE {col_name}=%s;" affected_rows = cursor.execute(sql, (value,)) connection.commit() except Exception as e: print(f"删除错误: {e}") return 0 return affected_rows def insert_row(values, tab_name='tbCourse'): if (not isinstance(values, (list, tuple))) or len(values) != 4: raise Exception('类型错误或长度不正确!!!') connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: try: with connection.cursor() as cursor: sql = f"INSERT INTO {tab_name} VALUES (%s, %s, %s, %s);" affected_rows = cursor.execute(sql, values) connection.commit() except Exception as e: print(f"插入错误: {e}") return 0 return affected_rows def insert_workrow(values, tab_name='homework'): if (not isinstance(values, (list, tuple))) or len(values) != 5: raise Exception('类型错误或长度不正确!!!') connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: try: with connection.cursor() as cursor: sql = f"INSERT INTO {tab_name} VALUES (%s, %s, %s, %s, %s);" affected_rows = cursor.execute(sql, values) connection.commit() except Exception as e: print(f"插入作业错误: {e}") return 0 return affected_rows if __name__ == '__main__': results = getData() print(results) for row in results: print(row) ``` ### 修复后的 `main_gui.py` ```python import FreeSimpleGUI as sg from fetch_data_mysql import getData, del_row, insert_row, insert_workrow, getData_aim from db_config import get_header def open_homework_search(): sublayout_homesearch = [ [sg.T('请输入要查询的学号:', justification='right'), sg.Input('', size=(50, None), key='-sub_Sno-')], [sg.Button('查询', key='-btn_search-')] ] subwin_homeworksearch = sg.Window('搜索作业', sublayout_homesearch, font=('微软雅黑', 13), modal=True) result = None while True: ev2, vals2 = subwin_homeworksearch.read() if ev2 in (sg.WIN_CLOSED, 'Exit'): break elif ev2 == '-btn_search-': student_id = vals2['-sub_Sno-'].strip() if student_id: result = getData_aim(student_id, tab_name='homework') # 查询作业表 sg.popup(f"找到{len(result)}条记录" if result else "未找到记录") else: sg.popup("请输入学号") subwin_homeworksearch.close() return result def open_rank_system(): layout = [ [sg.T('输入分数:'), sg.Input('', key='-INPUT_SCORE-')], [sg.T('等级结果:'), sg.Text('', size=(10, 1), key='-OUTPUT_GRADE-')], [sg.Button('转换', key='-btn_convert-')] ] window = sg.Window('分数等级转换器', layout, font=('微软雅黑', 13)) while True: event, values = window.read() if event == sg.WIN_CLOSED: break elif event == '-btn_convert-': try: score = float(values['-INPUT_SCORE-']) if score >= 90: grade = 'A' elif score >= 80: grade = 'B' elif score >= 70: grade = 'C' elif score >= 60: grade = 'D' else: grade = 'E' window['-OUTPUT_GRADE-'].update(grade) except ValueError: sg.popup_error('请输入有效数字!') window.close() def open_hundredsystem(): layout = [ [sg.T('原始分数:'), sg.Input('', key='-INPUT_VALUE-')], [sg.T('百分制:'), sg.Text('', size=(10, 1), key='-OUTPUT_PERCENT-')], [sg.Button('转换', key='-btn_convert-')] ] window = sg.Window('百分制转换器', layout, font=('微软雅黑', 13)) while True: event, values = window.read() if event == sg.WIN_CLOSED: break elif event == '-btn_convert-': try: raw_value = float(values['-INPUT_VALUE-']) percent_value = raw_value * 10 # 假设原始是0-10分,转换为百分制 window['-OUTPUT_PERCENT-'].update(f"{percent_value:.1f}%") except ValueError: sg.popup_error('请输入有效数字!') window.close() def open_addHomeworkWindow(): sublayout_homework = [ [sg.T('学号:'), sg.Input('', key='-sub_Sno-')], [sg.T('姓名:'), sg.Input('', key='-sub_Sname-')], [sg.T('课程号:'), sg.Input('', key='-sub_Cno-')], [sg.T('提交日期:'), sg.Input('', key='-sub_Hyime-')], [sg.T('评分:'), sg.Input('', key='-sub_Grade-')], [sg.Button('发布', key='-btn_submit-')] ] subwin = sg.Window('添加作业', sublayout_homework, font=('微软雅黑', 13), modal=True) add_affected_rows = 0 while True: event, values = subwin.read() if event in (sg.WIN_CLOSED, 'Exit'): break elif event == '-btn_submit-': vals = [ values['-sub_Sno-'], values['-sub_Sname-'], values['-sub_Cno-'], values['-sub_Hyime-'], values['-sub_Grade-'] ] add_affected_rows = insert_workrow(vals) break subwin.close() if add_affected_rows > 0: sg.popup('发布成功!') else: sg.popup('发布失败!') return add_affected_rows def open_addCourseWindow(): sublayout_course = [ [sg.T('课程号:'), sg.Input('', key='-sub_cno-')], [sg.T('课程名称:'), sg.Input('', key='-sub_cname-')], [sg.T('先修课:'), sg.Input('', key='-sub_cpno-')], [sg.T('学分:'), sg.Input('', key='-sub_ccredit-')], [sg.Button('确定', key='-btn_submit-')] ] subwin = sg.Window('添加课程', sublayout_course, font=('微软雅黑', 13), modal=True) add_affected_rows = 0 while True: event, values = subwin.read() if event in (sg.WIN_CLOSED, 'Exit'): break elif event == '-btn_submit-': vals = [ values['-sub_cno-'], values['-sub_cname-'], values['-sub_cpno-'] or None, values['-sub_ccredit-'] ] add_affected_rows = insert_row(vals) break subwin.close() if add_affected_rows > 0: sg.popup('添加成功!') else: sg.popup('添加失败!') return add_affected_rows def refreshData(table_key, tab_name): """刷新表格数据""" data = getData(tab_name=tab_name) window[table_key].update(data) return data if __name__ == '__main__': sg.theme('DefaultNoMoreNagging') # 初始化数据 data_ducsum = getData(tab_name='ducsum') header_ducsum = get_header(tab_name='ducsum') data_homework = getData(tab_name='homework') header_homework = get_header(tab_name='homework') data_courses = getData(tab_name='tbcourse') header_courses = get_header(tab_name='course') data_students = getData(tab_name='tbStuinfo') header_students = get_header(tab_name='student') header_sc = get_header(tab_name='sc') data_sc = getData(tab_name='sc') # 布局定义 - 为每个表格使用唯一的key Alsum_layout = [ [sg.Button('导入'), sg.Button('导出')], [sg.Table( values=data_ducsum, headings=header_ducsum, auto_size_columns=True, display_row_numbers=True, justification='left', num_rows=10, alternating_row_color='lightyellow', key='-TABLE_SUMMARY-', expand_x=True, expand_y=True )] ] Grade_layout = [ [sg.Text('评分标准转换', font=('微软雅黑', 16), justification='center')], [sg.VPush()], [sg.Column([ [sg.Push(), sg.Button('百分制转换', key='-btn_hundred_system', size=(15, 2)), sg.Push(), sg.Button('等级制转换', key='-btn_rank_system', size=(15, 2)), sg.Push()] ], expand_x=True)], [sg.VPush()] ] homework_layout = [ [ sg.Input(key='-INPUT_HOMEWORK_SEARCH-', size=(30, 1)), sg.Button('搜索', key='-btn_homework_search'), sg.Button('添加', key='-btn_add_homework-'), # 修正事件名称 sg.Button('删除', key='-btn_del_homework'), sg.Button('修改', key='-btn_edit_homework') ], [sg.Table( values=data_homework, headings=header_homework, auto_size_columns=True, display_row_numbers=True, justification='left', num_rows=10, alternating_row_color='lightyellow', key='-TABLE_HOMEWORK-', # 唯一key expand_x=True, expand_y=True, enable_events=True )], [sg.Button('上一页'), sg.Button('下一页')] ] course_layout = [ [sg.Table( values=data_courses, headings=header_courses, auto_size_columns=True, display_row_numbers=True, justification='left', num_rows=10, alternating_row_color='lightyellow', key='-TABLE_COURSE-', # 唯一key expand_x=True, expand_y=True, enable_events=True )], [ sg.Button('刷新', key='-btn_refresh_course-'), sg.Button('删除', key='-btn_del_course-'), sg.Button('添加', key='-btn_add_course-') ] ] student_layout = [ [sg.Table( values=data_students, headings=header_students, auto_size_columns=True, display_row_numbers=True, justification='left', num_rows=10, alternating_row_color='lightyellow', key='-TABLE_STUDENT-', # 唯一key expand_x=True, expand_y=True, enable_events=True )], [ sg.Button('刷新', key='-btn_refresh_student-'), sg.Button('删除', key='-btn_del_student-'), sg.Button('添加', key='-btn_add_student-') ] ] SC_layout = [ [sg.Table( values=data_sc, headings=header_sc, auto_size_columns=True, display_row_numbers=True, justification='left', num_rows=10, alternating_row_color='lightyellow', key='-TABLE_SC-', # 唯一key expand_x=True, expand_y=True, enable_events=True )], [ sg.Button('刷新', key='-btn_refresh_sc-'), sg.Button('删除', key='-btn_del_sc-'), sg.Button('添加', key='-btn_add_sc-') ] ] # 标签页布局 layout = [ [sg.TabGroup([ [ sg.Tab('首页', homework_layout, key='-tab_homework'), sg.Tab('设置', Grade_layout, key='-tab_grade'), sg.Tab('汇总', Alsum_layout, key='-tab_summary'), sg.Tab('课程表', course_layout, key='-tab_course'), sg.Tab('学生表', student_layout, key='-tab_student'), sg.Tab('选课表', SC_layout, key='-tab_sc') ] ], key='-TAB_GROUP-', tab_location='left', title_color='red', selected_title_color='green')] ] window = sg.Window('课后作业评分系统', layout, font=('微软雅黑', 14), size=(740, 580)) # 当前选择的数据 current_selection = { 'course': {'row': None, 'cno': None}, 'homework': {'row': None, 'sno': None}, 'student': {'row': None, 'sno': None}, 'sc': {'row': None} } while True: event, values = window.read() if event == sg.WIN_CLOSED: break # 刷新数据 if event == '-btn_refresh_course-': data_courses = refreshData('-TABLE_COURSE-', 'tbcourse') elif event == '-btn_refresh_student-': data_students = refreshData('-TABLE_STUDENT-', 'tbStuinfo') elif event == '-btn_refresh_homework-': data_homework = refreshData('-TABLE_HOMEWORK-', 'homework') elif event == '-btn_refresh_sc-': data_sc = refreshData('-TABLE_SC-', 'sc') # 课程删除 elif event == '-btn_del_course-': if current_selection['course']['row'] is not None: cno = current_selection['course']['cno'] if cno: aff_rows = del_row(cno, 'tbCourse', 'Cno') if aff_rows > 0: sg.popup(f'成功删除课程 {cno}') data_courses = refreshData('-TABLE_COURSE-', 'tbcourse') else: sg.popup('删除失败') else: sg.popup('请先选择课程') else: sg.popup('请先选择课程') # 添加课程 elif event == '-btn_add_course-': add_affected_rows = open_addCourseWindow() if add_affected_rows > 0: data_courses = refreshData('-TABLE_COURSE-', 'tbcourse') # 添加作业 elif event == '-btn_add_homework-': # 修正事件名称 add_affected_rows = open_addHomeworkWindow() if add_affected_rows > 0: data_homework = refreshData('-TABLE_HOMEWORK-', 'homework') # 分数转换功能 elif event == '-btn_hundred_system-': open_hundredsystem() elif event == '-btn_rank_system-': open_rank_system() # 作业搜索 elif event == '-btn_homework_search-': search_text = values['-INPUT_HOMEWORK_SEARCH-'].strip() if search_text: result = getData
阅读全文

相关推荐

db_config.py里有HOST='localhost' USER='root' PWD='root' DB_PORT=3306 DB_NAME='test'def get_header(tab_name='course'): ''' 根据表名称返回表的标题 :param tab_name: 表的名称 :return: list, 表的标题行 ''' header=None if tab_name=='course': header=['Cno', 'Cname', 'Cpno', 'Ccredit'] elif tab_name=='student': header=['Sno', 'Sname', 'Ssex', 'Sage', 'Sdept'] elif tab_name=='sc': header=['Sno', 'Cno', 'Grade'] elif tab_name=='homework': header=['Sno','Sname','Cno','Hyime','Grade'] elif tab_name=='ducsum': header=['Sno','Sname','Algrade','Avagrade','Rankwork'] return header def trans_data(dict_results): ''' 将[ {'Cno': '01', 'Cname': '高等数学', 'Cpno': None, 'Ccredit': 4}, {'Cno': '02', 'Cname': '大学物理', 'Cpno': '01', 'Ccredit': 3} ] 转换为:[('01', '高等数学', None, 4), ('02', '大学物理', '01', 3) ] :param dict_results: :return: ''' ll=[] for dict in dict_results: ll.append(list(dict.values())) return ll fetch_data_mysql.py里有import pymysql.cursors import db_config def getData(tab_name='tbcourse'): # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) # 使用pymysql.cursors.Cursor时,结果类似于: ( ('01', '高等数学', None, 4), ('02', '大学物理', '01', 3) ) # 使用pymysql.cursors.DictCursor时,结果类似于:[ {'Cno': '01', 'Cname': '高等数学', 'Cpno': None, 'Ccredit': 4}, {'Cno': '02', 'Cname': '大学物理', 'Cpno': '01', 'Ccredit': 3} ] with connection: with connection.cursor() as cursor: # Read a single record sql = f"SELECT * FROM {tab_name};" # cursor.execute(sql, ('[email protected]',)) cursor.execute(sql) results = cursor.fetchall() return results 这里有问题(下面) def getData_aim(tab_name='tbcourse'): # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) # 使用pymysql.cursors.Cursor时,结果类似于: ( ('01', '高等数学', None, 4), ('02', '大学物理', '01', 3) ) # 使用pymysql.cursors.DictCursor时,结果类似于:[ {'Cno': '01', 'Cname': '高等数学', 'Cpno': None, 'Ccredit': 4}, {'Cno': '02', 'Cname': '大学物理', 'Cpno': '01', 'Ccredit': 3} ] with connection: with connection.cursor() as cursor: # Read a single record sql = f"SELECT * FROM {tab_name} where department = 'Sno';" # cursor.execute(sql, ('[email protected]',)) cursor.execute(sql) results = cursor.fetchall() return results def del_row(cno, tab_name='tbCourse'): # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: try: with connection.cursor() as cursor: # 表格名称不能使用占位符,只能拼接字符串 sql = f"DELETE FROM {tab_name} where CNO=%s;" affected_rows=cursor.execute(sql, (cno,)) # connection is not autocommit by default. So you must commit to save your changes. connection.commit() except: return 0 return affected_rows def insert_row(values, tab_name='tbCourse'): # 这里我们只处理输入值数目为4个的情况 if ((not isinstance(values, list)) and (not isinstance(values,tuple))) or len(values)!=4: raise Exception('type error or length incorrect!!!') # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: try: with connection.cursor() as cursor: # 表格名称不能使用占位符,只能拼接字符串 sql = f"insert into {tab_name} values (%s, %s, %s, %s);" affected_rows = cursor.execute(sql, values) # connection is not autocommit by default. So you must commit to save your changes. connection.commit() except: return 0 return affected_rows def insert_workrow(values, tab_name='homework'): # 这里我们只处理输入值数目为5个的情况 if ((not isinstance(values, list)) and (not isinstance(values,tuple))) or len(values)!=5: raise Exception('type error or length incorrect!!!') # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: try: with connection.cursor() as cursor: # 表格名称不能使用占位符,只能拼接字符串 sql = f"insert into {tab_name} values (%s, %s, %s, %s, %s);" affected_rows = cursor.execute(sql, values) # connection is not autocommit by default. So you must commit to save your changes. connection.commit() except: return 0 return affected_rows if __name__ == '__main__': results=getData() print(results) for row in results: print(row) main_gui.py文件里有import FreeSimpleGUI as sg #需要切换为MySQL数据库,请将fetch_data_mssql更改为:fetch_data_mysql from fetch_data_mysql import getData, del_row, insert_row,insert_workrow,getData_aim这里和fetch.data.mysql里的问题一样连一起 from db_config import get_header def open_homework_search(): sublayout_homesearch = [ [sg.T('请输入要查询的学号:', justification='right'), sg.Input('', size=(50, None), key='-sub_Rname-')], [sg.Button('查询', key='-btn_search-')] # 修正2:添加缺失的查询按钮 ] subwin_homeworksearch = sg.Window('搜索', sublayout_homesearch, font=('微软雅黑', 13), modal=True) while True: ev2, dict_vals2 = subwin_homeworksearch.read() # 修正4:read()应小写 if ev2 in (sg.WIN_CLOSED, 'Exit'): break elif ev2 == '-btn_search-': # 修正5:匹配正确的按钮key student_id = dict_vals2['-sub_Rname-'].strip() or None # 修正6:实际执行查询逻辑(原代码直接获取全部数据) result = search_homework_by_student(student_id) sg.popup(f"找到{len(result)}条记录" if result else "未找到记录") break subwin_homeworksearch.close() return result if 'result' in locals() else None def open_rank_system(): layout = [ [sg.T('输入分数:', size=(10,None), justification='right'), sg.Input('', (20, None), key='-INPUT_SCORE-')], [sg.T('等级结果:', size=(10,None), justification='right'), sg.Text('', size=(20,1), key='-OUTPUT_GRADE-')], [sg.Button('转换', key='-btn_rank_system', size=(10,None))] ] window = sg.Window('分数等级转换器', layout, font=('微软雅黑', 13)) while True: event, values = window.read() if event == sg.WIN_CLOSED: break elif event == '-btn_rank_system': try: score = float(values['-INPUT_SCORE-']) if score >= 90: grade = 'A' elif score >= 80: grade = 'B' elif score >= 70: grade = 'C' elif score >= 60: grade = 'D' else: grade = 'E' window['-OUTPUT_GRADE-'].update(grade) except ValueError: sg.popup_error('请输入有效数字!') window.close() def open_hundredsystem(): layout = [ [sg.T('原始数值:', size=(10,None), justification='right'), sg.Input('', (20, None), key='-INPUT_VALUE-')], [sg.T('百分制结果:', size=(10,None), justification='right'), sg.Text('', size=(20,1), key='-OUTPUT_PERCENT-')], [sg.Button('转换', key='-btn_hundred_system', size=(10,None))] ] window = sg.Window('百分制转换器', layout, font=('微软雅黑', 13)) while True: event, values = window.read() if event == sg.WIN_CLOSED: break elif event == '-btn_hundred_system': try: raw_value = float(values['-INPUT_VALUE-']) percent_value = raw_value * 0.1 *0.1 window['-OUTPUT_PERCENT-'].update(f"{percent_value:.2f}%") except ValueError: sg.popup_error('请输入有效数字!') window.close() def open_addHomeworkWindow(): sublayout_homework = [ [sg.T('学号:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Sno-' )], [sg.T('姓名:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Sname-' )], [sg.T('课后任务:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Cno-' )], [sg.T('提交日期:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Hyime-' )], [sg.T('评分:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Grade-' )], [sg.Ok('发布', key='-btn_sub_addhomework-',size=(10,None))] ] subwin_addhomework = sg.Window('添加新任务(作业)', sublayout_homework, font=('微软雅黑', 13), modal=True) add_affected_rows = 0 while True: ev2, dict_vals2 = subwin_addhomework.Read() if ev2 == sg.WIN_CLOSED or ev2 == 'Exit': break elif ev2 == '-btn_sub_addhomework-': dict_vals2['-sub_Sno-'] = None if dict_vals2['-sub_Sno-']=='' else dict_vals2['-sub_Sno-'] add_affected_rows = insert_workrow(list(dict_vals2.values()), tab_name='homework') break subwin_addhomework.close() if add_affected_rows>0: sg.popup_timed('发布成功!') if add_affected_rows<=0: sg.popup_timed('发布失败!') return add_affected_rows def open_addCourseWindow(): sublayout_course = [ [sg.T('课程号:', size=(10,None), justification='right'), sg.Input('', (50, None), key='-sub_cno-' )], [sg.T('课程名称:', size=(10,None), justification='right'), sg.Input('', (50, None), key='-sub_cname-' )], [sg.T('先修课:', size=(10,None), justification='right'), sg.Input('', (50, None), key='-sub_cpno-' )], [sg.T('学分:', size=(10,None), justification='right'), sg.Input('', (50, None), key='-sub_ccredit-' )], [sg.Ok('确定', key='-btn_sub_addcourse-',size=(10,None))] ] subwin_addCourse = sg.Window('添加课程信息', sublayout_course, font=('微软雅黑', 13), modal=True) add_affected_rows = 0 while True: ev2, dict_vals2 = subwin_addCourse.Read() if ev2 == sg.WIN_CLOSED or ev2 == 'Exit': break elif ev2 == '-btn_sub_addcourse-': dict_vals2['-sub_cpno-'] = None if dict_vals2['-sub_cpno-']=='' else dict_vals2['-sub_cpno-'] add_affected_rows = insert_row(list(dict_vals2.values()), tab_name='tbCourse') break subwin_addCourse.close() if add_affected_rows>0: sg.popup_timed('插入课程信息成功!') return add_affected_rows def refreshData(table_key='-TABLE_course-', tab_name='tbcourse'): # 刷新表的显示 data_courses = getData(tab_name=tab_name) window[table_key].update(data_courses) return data_courses if __name__ == '__main__': sg.theme('DefaultNoMoreNagging') data_ducsum = getData(tab_name='ducsum') header_ducsum = get_header(tab_name='ducsum') data_homework = getData(tab_name='homework') header_homework = get_header(tab_name='homework') data_courses = getData(tab_name='tbcourse') header_courses = get_header(tab_name='course') data_students = getData(tab_name='tbStuinfo') header_students = get_header(tab_name='student') header_sc = get_header(tab_name='sc') Alsum_layout = [ [sg.Button(button_text='导入'),sg.Button(button_text='导出')], [sg.Table(values=data_ducsum, headings=header_ducsum, size=(550,400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_course-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a course table') ] ] Grade_layout = [ [sg.Column([ [sg.Text('评分标准模式', justification='center', expand_x=True)], [sg.Push(), sg.Button('百分制',key='-btn_hundred_system'), sg.Push(), sg.Button('分级制',key='-btn_rank_system'), sg.Push()] ], expand_x=True)] ] homework_layout = [ [sg.InputText(),sg.Button(button_text='搜索',key='-btn_homework_search'), sg.Button(button_text='添加',key='-btn_add_homework'), sg.Button(button_text='删除'), sg.Button(button_text='修改') ], [sg.Table(values=data_homework, headings=header_homework, size=(550,400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_course-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a course table') ], [sg.Button(button_text='上一页', key='-btn_refresh_course-'), sg.Button(button_text='下一页', key='-btn_del_course-') ] ] course_layout = [ [sg.Table(values=data_courses, headings=header_courses, size=(550,400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_course-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a course table') ], [sg.Button(button_text='刷新', key='-btn_refresh_course-'), sg.Button(button_text='删除', key='-btn_del_course-'), sg.Button(button_text='添加', key='-btn_add_course-') ] ] student_layout = [ [sg.Table(values=data_students, headings=header_students, size=(550, 400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_Student-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a student table') ], [sg.Button(button_text='刷新', key='-btn_refresh_student-'), sg.Button(button_text='删除', key='-btn_del_student-'), sg.Button(button_text='添加', key='-btn_add_student-') ] ] SC_layout = [[sg.Table(values=[[]], headings=header_sc, # size=(550, 400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_SC-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a SC table') ], [sg.Button(button_text='刷新', key='-btn_refresh_sc-'), sg.Button(button_text='删除', key='-btn_del_sc-'), sg.Button(button_text='添加', key='-btn_add_sc-') ] ] layout = [[sg.TabGroup([[sg.Tab('首页', homework_layout, key='-tab_homework'), sg.Tab('设置', Grade_layout,key='-tab_course-'), sg.Tab('汇总', Alsum_layout,key='-tab_course-'), sg.Tab('课程表', course_layout, key='-tab_course-'), sg.Tab('学生表', student_layout, key='-tab_student-'), sg.Tab('选课表', SC_layout, key='-tab_sc-')]], key='-group2-', title_color='red', selected_title_color='green', tab_location='left') ]] window = sg.Window('课后作业评分系统', layout, default_element_size=(10, 1),size=(740,580), font=('微软雅黑', 14)) cur_cno=None #当前的选择的课程号 cur_course_row_number=None #当前课程表中被选择的行号,行号从0开始,-1为标题行 subwin_addCourse_active = False subwin_addCourse = None while True: event, values = window.read() # sg.popup_non_blocking(event, values) # print(event) # print(values) if event == sg.WIN_CLOSED: # always, always give a way out! break if event=='-btn_del_course-': # 删除选择的课程号 aff_rows = del_row(cno=cur_cno, tab_name='tbCourse') print('影响的行数:', aff_rows) if(aff_rows>0): data_courses = list(data_courses) data_courses.pop(cur_course_row_number) #从数据表格中移除选择的行数据 window['-TABLE_course-'].update(data_courses) cur_course_row_number = None cur_cno = None elif event=='-btn_add_course-': # 添加课程 # 先弹窗,获取信息 add_affected_rows = open_addCourseWindow() if add_affected_rows>0: data_courses = refreshData(table_key='-TABLE_course-', tab_name='tbcourse') elif event=='-btn_refresh_course-': # 刷新课程表的显示 data_courses = refreshData(table_key='-TABLE_course-', tab_name='tbcourse') elif event=='-btn_add_homework': add_affected_row = open_addHomeworkWindow() if add_affected_row>0: data_courses = refreshData(table_key='-TABLE_course-',tab_name='tbcourse') elif event=='-btn_hundred_system': add_affected_row = open_hundredsystem() if add_affected_row>0: data_courses = refreshData(table_key='-TABLE_course-',tab_name='tbcourse') elif event=='-btn_rank_system': add_affected_row = open_rank_system() if add_affected_row>0: data_courses = refreshData(table_key='-TABLE_course-',tab_name='tbcourse') elif event=='-btn_homework_search': add_affected_row = open_homework_search() if add_affected_row>0: data_courses = refreshData(table_key='-TABLE_course-',tab_name='tbcourse') if isinstance(event, tuple): # TABLE CLICKED Event has value in format ('-TABLE-', '+CLICKED+', (row,col)) if event[0] == '-TABLE_course-': cur_course_row_number = event[2][0] col_number = event[2][1] if cur_course_row_number is not None: # 获取鼠标点击行的数据 cur_row_value = data_courses[cur_course_row_number] # 获取点击行的Cno cur_cno = cur_row_value[0] print('当前选择的课程号:', cur_cno) window.close() 根据上述代码修改优化,使代码能成功运行,实现功能

# # 【MySQL】和【SQL Server】 二选一 # # 1. MySQL数据库连接信息 HOST='localhost' USER='root' PWD='root' DB_PORT=3306 DB_NAME='test' # 2. SQL server数据库连接信息 MSSQL_HOST=r'LUOGEPC1103\SQLEXPRESS2014' MSSQL_USER='sa' MSSQL_PWD='123456' MSSQL_PORT=1433 MSSQL_DB_NAME='test' MSSQL_Chartset='GB2312' def get_header(tab_name='course'): ''' 根据表名称返回表的标题 :param tab_name: 表的名称 :return: list, 表的标题行 ''' header=None if tab_name=='course': header=['Cno', 'Cname', 'Cpno', 'Ccredit'] elif tab_name=='student': header=['Sno', 'Sname', 'Ssex', 'Sage', 'Sdept'] elif tab_name=='sc': header=['Sno', 'Cno', 'Grade'] elif tab_name=='homework': header=['Sno','Sname','Cno','Hyime','Grade'] elif tab_name=='ducsum': header=['Sno','Sname','Algrade','Avagrade','Rankwork'] return header def trans_data(dict_results): ''' 将[ {'Cno': '01', 'Cname': '高等数学', 'Cpno': None, 'Ccredit': 4}, {'Cno': '02', 'Cname': '大学物理', 'Cpno': '01', 'Ccredit': 3} ] 转换为:[('01', '高等数学', None, 4), ('02', '大学物理', '01', 3) ] :param dict_results: :return: ''' ll=[] for dict in dict_results: ll.append(list(dict.values())) return llimport pymysql.cursors import db_config def getData(tab_name='tbcourse'): # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) # 使用pymysql.cursors.Cursor时,结果类似于: ( ('01', '高等数学', None, 4), ('02', '大学物理', '01', 3) ) # 使用pymysql.cursors.DictCursor时,结果类似于:[ {'Cno': '01', 'Cname': '高等数学', 'Cpno': None, 'Ccredit': 4}, {'Cno': '02', 'Cname': '大学物理', 'Cpno': '01', 'Ccredit': 3} ] with connection: with connection.cursor() as cursor: # Read a single record sql = f"SELECT * FROM {tab_name};" # cursor.execute(sql, ('[email protected]',)) cursor.execute(sql) results = cursor.fetchall() return results def getData_aim(Sno, tab_name='tbcourse'): # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) # 使用pymysql.cursors.Cursor时,结果类似于: ( ('01', '高等数学', None, 4), ('02', '大学物理', '01', 3) ) # 使用pymysql.cursors.DictCursor时,结果类似于:[ {'Cno': '01', 'Cname': '高等数学', 'Cpno': None, 'Ccredit': 4}, {'Cno': '02', 'Cname': '大学物理', 'Cpno': '01', 'Ccredit': 3} ] with connection: with connection.cursor() as cursor: # Read a single record sql = f"SELECT * FROM {tab_name}where Sno=%s;" affected_rows=cursor.execute(sql, (Sno,)) # cursor.execute(sql, ('[email protected]',)) cursor.execute(sql) results = cursor.fetchall() return results def del_row(cno, tab_name='tbCourse'): # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: try: with connection.cursor() as cursor: # 表格名称不能使用占位符,只能拼接字符串 sql = f"DELETE FROM {tab_name} where CNO=%s;" affected_rows = cursor.execute(sql, values) # connection is not autocommit by default. So you must commit to save your changes. connection.commit() except: return 0 return affected_rows def insert_row(values, tab_name='tbCourse'): # 这里我们只处理输入值数目为4个的情况 if ((not isinstance(values, list)) and (not isinstance(values,tuple))) or len(values)!=4: raise Exception('type error or length incorrect!!!') # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: try: with connection.cursor() as cursor: # 表格名称不能使用占位符,只能拼接字符串 sql = f"insert into {tab_name} values (%s, %s, %s, %s);" affected_rows = cursor.execute(sql, values) # connection is not autocommit by default. So you must commit to save your changes. connection.commit() except: return 0 return affected_rows def insert_workrow(values, tab_name='homework'): # 这里我们只处理输入值数目为5个的情况 if ((not isinstance(values, list)) and (not isinstance(values,tuple))) or len(values)!=5: raise Exception('type error or length incorrect!!!') # Connect to the database connection = pymysql.connect(host=db_config.HOST, user=db_config.USER, port=db_config.DB_PORT, password=db_config.PWD, database=db_config.DB_NAME, cursorclass=pymysql.cursors.Cursor) with connection: try: with connection.cursor() as cursor: # 表格名称不能使用占位符,只能拼接字符串 sql = f"insert into {tab_name} values (%s, %s, %s, %s, %s);" affected_rows = cursor.execute(sql, values) # connection is not autocommit by default. So you must commit to save your changes. connection.commit() except: return 0 return affected_rows if __name__ == '__main__': results=getData() print(results) for row in results: print(row) import FreeSimpleGUI as sg #需要切换为MySQL数据库,请将fetch_data_mssql更改为:fetch_data_mysql from fetch_data_mysql import getData, del_row, insert_row,insert_workrow,getData_aim from db_config import get_header def open_homework_search(): sublayout_homesearch = [ [sg.T('请输入要查询的学号:', justification='right'), sg.Input('', size=(50, None), key='-sub_Rname-')], [sg.Button('查询', key='-btn_search-')] ] subwin_homeworksearch = sg.Window('搜索', sublayout_homesearch, font=('微软雅黑', 13), modal=True) while True: ev2, dict_vals2 = subwin_homeworksearch.read() if ev2 in (sg.WIN_CLOSED, 'Exit'): break elif ev2 == '-btn_search-': student_id = dict_vals2['-sub_Rname-'].strip() or None result = getData_aim(student_id) sg.popup(f"找到{len(result)}条记录" if result else "未找到记录") break subwin_homeworksearch.close() return result if 'result' in locals() else None def open_rank_system(): layout = [ [sg.T('输入分数:', size=(10,None), justification='right'), sg.Input('', (20, None), key='-INPUT_SCORE-')], [sg.T('等级结果:', size=(10,None), justification='right'), sg.Text('', size=(20,1), key='-OUTPUT_GRADE-')], [sg.Button('转换', key='-btn_rank_system', size=(10,None))] ] window = sg.Window('分数等级转换器', layout, font=('微软雅黑', 13)) while True: event, values = window.read() if event == sg.WIN_CLOSED: break elif event == '-btn_rank_system': try: score = float(values['-INPUT_SCORE-']) if score >= 90: grade = 'A' elif score >= 80: grade = 'B' elif score >= 70: grade = 'C' elif score >= 60: grade = 'D' else: grade = 'E' window['-OUTPUT_GRADE-'].update(grade) except ValueError: sg.popup_error('请输入有效数字!') window.close() def open_hundredsystem(): layout = [ [sg.T('原始数值:', size=(10,None), justification='right'), sg.Input('', (20, None), key='-INPUT_VALUE-')], [sg.T('百分制结果:', size=(10,None), justification='right'), sg.Text('', size=(20,1), key='-OUTPUT_PERCENT-')], [sg.Button('转换', key='-btn_hundred_system', size=(10,None))] ] window = sg.Window('百分制转换器', layout, font=('微软雅黑', 13)) while True: event, values = window.read() if event == sg.WIN_CLOSED: break elif event == '-btn_hundred_system': try: raw_value = float(values['-INPUT_VALUE-']) percent_value = raw_value * 0.1 *0.1 window['-OUTPUT_PERCENT-'].update(f"{percent_value:.2f}%") except ValueError: sg.popup_error('请输入有效数字!') window.close() def open_addHomeworkWindow(): sublayout_homework = [ [sg.T('学号:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Sno-' )], [sg.T('姓名:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Sname-' )], [sg.T('课后任务:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Cno-' )], [sg.T('提交日期:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Hyime-' )], [sg.T('评分:', size=(None,None), justification='right'), sg.Input('', (50, None), key='-sub_Grade-' )], [sg.Ok('发布', key='-btn_sub_addhomework-',size=(10,None))] ] subwin_addhomework = sg.Window('添加新任务(作业)', sublayout_homework, font=('微软雅黑', 13), modal=True) add_affected_rows = 0 while True: ev2, dict_vals2 = subwin_addhomework.Read() if ev2 == sg.WIN_CLOSED or ev2 == 'Exit': break elif ev2 == '-btn_sub_addhomework-': dict_vals2['-sub_Sno-'] = None if dict_vals2['-sub_Sno-']=='' else dict_vals2['-sub_Sno-'] add_affected_rows = insert_workrow(list(dict_vals2.values()), tab_name='homework') break subwin_addhomework.close() if add_affected_rows>0: sg.popup_timed('发布成功!') if add_affected_rows<=0: sg.popup_timed('发布失败!') return add_affected_rows def open_addCourseWindow(): sublayout_course = [ [sg.T('课程号:', size=(10,None), justification='right'), sg.Input('', (50, None), key='-sub_cno-' )], [sg.T('课程名称:', size=(10,None), justification='right'), sg.Input('', (50, None), key='-sub_cname-' )], [sg.T('先修课:', size=(10,None), justification='right'), sg.Input('', (50, None), key='-sub_cpno-' )], [sg.T('学分:', size=(10,None), justification='right'), sg.Input('', (50, None), key='-sub_ccredit-' )], [sg.Ok('确定', key='-btn_sub_addcourse-',size=(10,None))] ] subwin_addCourse = sg.Window('添加课程信息', sublayout_course, font=('微软雅黑', 13), modal=True) add_affected_rows = 0 while True: ev2, dict_vals2 = subwin_addCourse.Read() if ev2 == sg.WIN_CLOSED or ev2 == 'Exit': break elif ev2 == '-btn_sub_addcourse-': dict_vals2['-sub_cpno-'] = None if dict_vals2['-sub_cpno-']=='' else dict_vals2['-sub_cpno-'] add_affected_rows = insert_row(list(dict_vals2.values()), tab_name='tbCourse') break subwin_addCourse.close() if add_affected_rows>0: sg.popup_timed('插入课程信息成功!') return add_affected_rows def refreshData(table_key='-TABLE_course-', tab_name='tbcourse'): # 刷新表的显示 data_courses = getData(tab_name=tab_name) window[table_key].update(data_courses) return data_courses if __name__ == '__main__': sg.theme('DefaultNoMoreNagging') data_ducsum = getData(tab_name='ducsum') header_ducsum = get_header(tab_name='ducsum') data_homework = getData(tab_name='homework') header_homework = get_header(tab_name='homework') data_courses = getData(tab_name='tbcourse') header_courses = get_header(tab_name='course') data_students = getData(tab_name='tbStuinfo') header_students = get_header(tab_name='student') header_sc = get_header(tab_name='sc') Alsum_layout = [ [sg.Button(button_text='导入'),sg.Button(button_text='导出')], [sg.Table(values=data_ducsum, headings=header_ducsum, size=(550,400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_course-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a course table') ] ] Grade_layout = [ [sg.Column([ [sg.Text('评分标准模式', justification='center', expand_x=True)], [sg.Push(), sg.Button('百分制',key='-btn_hundred_system'), sg.Push(), sg.Button('分级制',key='-btn_rank_system'), sg.Push()] ], expand_x=True)] ] homework_layout = [ [sg.InputText(),sg.Button(button_text='搜索',key='-btn_homework_search'), sg.Button(button_text='添加',key='-btn_add_homework'), sg.Button(button_text='删除'), sg.Button(button_text='修改') ], [sg.Table(values=data_homework, headings=header_homework, size=(550,400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_course-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a course table') ], [sg.Button(button_text='上一页', key='-btn_refresh_course-'), sg.Button(button_text='下一页', key='-btn_del_course-') ] ] course_layout = [ [sg.Table(values=data_courses, headings=header_courses, size=(550,400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_course-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a course table') ], [sg.Button(button_text='刷新', key='-btn_refresh_course-'), sg.Button(button_text='删除', key='-btn_del_course-'), sg.Button(button_text='添加', key='-btn_add_course-') ] ] student_layout = [ [sg.Table(values=data_students, headings=header_students, size=(550, 400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_Student-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a student table') ], [sg.Button(button_text='刷新', key='-btn_refresh_student-'), sg.Button(button_text='删除', key='-btn_del_student-'), sg.Button(button_text='添加', key='-btn_add_student-') ] ] SC_layout = [[sg.Table(values=[[]], headings=header_sc, # size=(550, 400), max_col_width=100, auto_size_columns=False, display_row_numbers=False, justification='left', num_rows=15, alternating_row_color='lightyellow', key='-TABLE_SC-', selected_row_colors='red on yellow', enable_events=True, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks tooltip='This is a SC table') ], [sg.Button(button_text='刷新', key='-btn_refresh_sc-'), sg.Button(button_text='删除', key='-btn_del_sc-'), sg.Button(button_text='添加', key='-btn_add_sc-') ] ] layout = [[sg.TabGroup([[sg.Tab('首页', homework_layout, key='-tab_homework'), sg.Tab('设置', Grade_layout,key='-tab_course-'), sg.Tab('汇总', Alsum_layout,key='-tab_course-'), sg.Tab('课程表', course_layout, key='-tab_course-'), sg.Tab('学生表', student_layout, key='-tab_student-'), sg.Tab('选课表', SC_layout, key='-tab_sc-')]], key='-group2-', title_color='red', selected_title_color='green', tab_location='left') ]] window = sg.Window('课后作业评分系统', layout, default_element_size=(10, 1),size=(740,580), font=('微软雅黑', 14)) cur_cno=None #当前的选择的课程号 cur_course_row_number=None #当前课程表中被选择的行号,行号从0开始,-1为标题行 subwin_addCourse_active = False subwin_addCourse = None while True: event, values = window.read() # sg.popup_non_blocking(event, values) # print(event) # print(values) if event == sg.WIN_CLOSED: # always, always give a way out! break if event=='-btn_del_course-': # 删除选择的课程号 aff_rows = del_row(cno=cur_cno, tab_name='tbCourse') print('影响的行数:', aff_rows) if(aff_rows>0): data_courses = list(data_courses) data_courses.pop(cur_course_row_number) #从数据表格中移除选择的行数据 window['-TABLE_course-'].update(data_courses) cur_course_row_number = None cur_cno = None elif event=='-btn_add_course-': # 添加课程 # 先弹窗,获取信息 add_affected_rows = open_addCourseWindow() if add_affected_rows>0: data_courses = refreshData(table_key='-TABLE_course-', tab_name='tbcourse') elif event=='-btn_refresh_course-': # 刷新课程表的显示 data_courses = refreshData(table_key='-TABLE_course-', tab_name='tbcourse') elif event=='-btn_add_homework': add_affected_row = open_addHomeworkWindow() if add_affected_row>0: data_courses = refreshData(table_key='-TABLE_course-',tab_name='tbcourse') elif event=='-btn_hundred_system': add_affected_row = open_hundredsystem() if add_affected_row>0: data_courses = refreshData(table_key='-TABLE_course-',tab_name='tbcourse') elif event=='-btn_rank_system': add_affected_row = open_rank_system() if add_affected_row>0: data_courses = refreshData(table_key='-TABLE_course-',tab_name='tbcourse') elif event=='-btn_homework_search': add_affected_row = open_homework_search() if add_affected_row>0: data_courses = refreshData(table_key='-TABLE_course-',tab_name='tbcourse') if isinstance(event, tuple): # TABLE CLICKED Event has value in format ('-TABLE-', '+CLICKED+', (row,col)) if event[0] == '-TABLE_course-': cur_course_row_number = event[2][0] col_number = event[2][1] if cur_course_row_number is not None: # 获取鼠标点击行的数据 cur_row_value = data_courses[cur_course_row_number] # 获取点击行的Cno cur_cno = cur_row_value[0] print('当前选择的课程号:', cur_cno) window.close() 修改上述代码,使之功能正常运行

大家在看

recommend-type

Cisco ONS 15454 SDH多业务传输平台

Cisco ONS 15454 SDH多业务传输平台凭借内置的“网络感知”、基于Java的图形用户界面 (GUI)-CISCO 传输控制器 (CTC),能提供可扩展的带宽、容易的交叉复接 (grooming)、A-Z电路配置、自动网络拓扑发现和用户带宽管理,允许运营商围绕订户需求来设计传输网而不受设备限制。
recommend-type

欧瑞最新E2000变频器说明书

欧瑞最新E2000变频器说明书,官方发布的最新版本,欢迎大家下载!
recommend-type

蒙特卡罗剂量模拟和可视化工具包:一组旨在帮助临床医生和研究人员使用 GEANT4 或 TOPAS 的 Matlab 函数-matlab开发

这里有 3 组代码,旨在帮助临床医生和研究人员将 GEANT4 或 TOPAS (MC) 与 3D Slicer 结合使用进行剂量可视化和比较 第一段代码“STLfromDicomRN.m”采用 Varian Eclipse 生成的双散射质子计划的 Dicom 计划文件,并以“.STL”格式生成计划中的Kong径和补偿器模型。 此文件使用 zip 文件中包含的“stlwrite”和“surf2solid”函数。 这些文件可以导入到 MC 模拟几何中。 第二个是一组用于处理Dicom剂量文件和分析剂量的代码。 “NormalizeDicomDose.m”代码将 MC 剂量标准化为 Eclipse 剂量等中心处的剂量,并包含有关如何标准化为其他点或体积的说明。 “ProfilePlot.m”代码只是生成比较两点之间两个剂量文件的剂量的剂量曲线。 包含的是一个 matlab gui,它在您
recommend-type

libdmtx-vs2013-64-32-lib-dll(带h文件).zip

包含libdmtx0.7.2和0.7.4在x86和x64环境下的lib和dll,由VS2013编译源码生成
recommend-type

通达信DLL插件编程示例(源码)

通达信DLL插件编程示例(源码)

最新推荐

recommend-type

arc-spring-boot-starter-0.107.0-sources.jar

arc-spring-boot-starter-0.107.0-sources.jar
recommend-type

chat-sdk-1.0.0-sources.jar

chat-sdk-1.0.0-sources.jar
recommend-type

core-1.1.1-javadoc.jar

core-1.1.1-javadoc.jar
recommend-type

service_2.11-0.0.102-javadoc.jar

service_2.11-0.0.102-javadoc.jar
recommend-type

arc-agent-client-0.85.0.jar

arc-agent-client-0.85.0.jar
recommend-type

Odoo与WooCommerce双向数据同步解决方案

在探讨Odoo与WooCommerce连接器模块之前,需要先了解几个关键的IT概念,比如Odoo,WooCommerce,ERP系统,以及如何将它们通过一个名为“connector-woocommerce”的Python模块整合在一起。 ### Odoo与WooCommerce的连接 **Odoo** 是一个全面的企业资源规划(ERP)软件包,用于管理企业中的所有业务流程。它包含了一系列的模块,覆盖了从会计、库存管理到电子商务和客户关系管理的各个方面。Odoo强大的模块化系统使其可以高度定制化,以适应不同企业的特定需求。 **WooCommerce** 是一个开源的电子商务解决方案,主要设计用于集成WordPress,是目前使用最广泛的电子商务平台之一。它能够提供完整的在线商店功能,并且可以通过众多插件进行扩展,以满足不同的业务需求。 ### ERP系统与电子商务的整合 在现代商务环境中,ERP系统和电子商务平台需要紧密集成。ERP系统负责内部业务流程的管理,而电子商务平台则负责与客户的直接交互,包括产品展示、订单处理、支付处理等。当两者被整合在一起时,它们可以提供无缝的工作流,例如实时库存同步、自动更新订单状态、以及统一的客户数据管理。 ### WooCommerceERPconnect **WooCommerceERPconnect**,也即“connector-woocommerce”,是一款专为连接Odoo ERP系统与WooCommerce电子商务平台设计的双向连接器。这个模块能够使得Odoo中的产品信息、订单信息、库存信息以及客户信息能够实时地同步到WooCommerce中。同样,从WooCommerce平台接收到的订单也可以实时地传输并反映到Odoo系统内。这样一来,企业可以确保他们的ERP系统和在线商店始终保持信息的一致性,极大地提高了业务效率和客户满意度。 ### 连接器的兼容性和实现方式 提到该连接器与**OpenERP 8.0** 和 **WooCommerce 2.4.x** 100% 兼容,说明开发团队在设计时考虑了特定版本间的兼容性问题,确保了连接器能够在这些版本上正常工作。考虑到Odoo是由OpenERP发展而来,它强调了此连接器是为最新版本的Odoo所设计,以确保能利用Odoo提供的最新功能。 **Python** 在这里扮演了重要的角色,因为Python是Odoo的开发语言,并且在连接器模块中也广泛使用。Python的易用性、灵活性以及丰富的库支持,使得开发者能够快速开发出功能强大的模块。该连接器模块很可能使用了Python进行后端逻辑处理,借助Odoo提供的API与WooCommerce进行数据交互。 ### 文件压缩包内容 关于提供的**connector-woocommerce-8.0** 压缩包,这显然是一个专为Odoo版本8.0设计的WooCommerce连接器。文件包内可能包括了所有必要的安装文件、配置脚本、以及可能的文档说明。安装这样的模块通常需要对Odoo有一定的了解,包括如何部署新模块,以及如何配置模块以确保其能够正确与WooCommerce通信。 ### 实施电子商务与ERP整合的考虑因素 企业实施ERP与电子商务整合时,需考虑以下因素: - **数据同步**:确保产品数据、库存数据、价格、订单信息等在Odoo和WooCommerce之间实时准确地同步。 - **安全性和稳定性**:在数据传输和处理过程中保障数据安全,并确保整合后的系统稳定运行。 - **扩展性**:随着业务的扩展,连接器需要能够适应更多的用户、更多的产品和更复杂的数据交互。 - **维护和更新**:连接器需要定期维护和更新,以适应Odoo和WooCommerce的版本迭代。 在进行整合时,可能需要进行定制开发以适应特定的业务逻辑和工作流程。这往往涉及到对Odoo或WooCommerce API的深入了解,并可能需要调整连接器的源代码以满足特殊需求。 ### 总结 通过Odoo连接器WooCommerce模块的使用,企业可以有效地整合其ERP系统与电子商务平台,实现数据的一体化管理,提高工作效率,优化客户体验。而这一切的实现,都离不开对Odoo、WooCommerce以及连接器背后的技术栈(如Python)的深入理解。
recommend-type

Linux系统运维知识大揭秘

### Linux 系统运维知识大揭秘 #### 1. 标准输入、输出与错误 在 Linux 系统中,标准输入(STDIN)、标准输出(STDOUT)和标准错误(STDERR)是非常基础且重要的概念。 |名称|默认目标|重定向使用|文件描述符编号| | ---- | ---- | ---- | ---- | |STDIN|计算机键盘|< (等同于 0<)|0| |STDOUT|计算机显示器|> (等同于 1>)|1| |STDERR|计算机显示器|2>|2| 常见的 Bash 重定向器如下: |重定向器|解释| | ---- | ---- | |> (等同于 1>)|重定向 STDOUT。
recommend-type

int arr1[4] = {1,2,3,4}; int arr2[4] = { 1,2 }; int arr[4] = {0];//所有元素为0 static int arr3[3]; int arr4[4]; cout << "arr1:"<<arr1[0] << arr1[1] << arr1[2] << arr1[3] << endl; cout << "arr2:" << arr2[0] << arr2[1] << arr2[2] << arr2[3] << endl; cout << "arr3:" << arr3[0] << arr3[1] << arr3[2] << arr3[3] << endl; cout << "arr4:" << arr4[0] << arr4[1] << arr4[2] << arr4[3] << endl;

### C++ 中数组的初始化与未初始化元素的默认值行为 在 C++ 中,数组的初始化行为取决于其类型(如内置数组、`std::array` 或 `std::vector`)以及使用的初始化语法。以下是对不同情况的详细分析。 #### 内置数组的初始化与默认值 对于内置数组(如 `int arr[10];`),如果未显式初始化,则其元素的值是未定义的。这意味着这些元素可能包含任意的垃圾值,具体取决于编译器和运行环境。例如: ```cpp int arr[10]; // 未初始化,元素值未定义 ``` 如果希望所有元素初始化为零,可以使用值初始化语法: ```cpp int arr[
recommend-type

基于Lerna和Module Federation的Micro前端架构

### 知识点一:微前端架构(microfrontend) 微前端是一种架构设计风格,它将一个大型前端应用拆分成多个较小的独立前端应用,每个独立的前端应用可以被单独开发、部署和扩展。微前端架构有助于团队的独立工作,降低了大规模项目的技术债务,提高了系统的可维护性和可扩展性。 #### 关键概念: 1. **独立自治:** 每个微前端都可以独立于整体应用进行开发、测试和部署。 2. **技术多样性:** 不同的微前端可以使用不同的前端技术栈。 3. **共享基础设施:** 为了保持一致性,微前端之间可以共享工具、框架和库。 4. **通信机制:** 微前端之间需要有通信机制来协调它们的行为。 ### 知识点二:Lerna Lerna 是一个优化了多包管理的 JavaScript 库,专用于维护具有多个包的大型JavaScript项目。Lerna 可以帮助开发者在一个仓库中管理多个包,减少重复的构建步骤,并且在包之间共享依赖。 #### 核心功能: 1. **作用域包管理:** Lerna 可以帮助开发者创建和管理仓库中的本地作用域包。 2. **自动链接:** 自动链接内部依赖,减少开发中的配置复杂性。 3. **版本管理:** 方便地处理多包项目的版本发布和变更。 4. **并行构建:** 加速构建过程,因为可以并行地构建多个包。 ### 知识点三:Module Federation Module Federation 是 Webpack 5 引入的一个实验性功能,它允许运行时从多个构建中动态加载代码。这使得在不同的前端应用之间共享模块成为可能,这是实现微前端架构的关键技术。 #### 关键特性: 1. **远程和本地模块共享:** 它不仅可以在应用程序之间共享模块,还可以在应用程序内部进行模块共享。 2. **代码分割:** 可以实现更好的代码分割和懒加载。 3. **独立部署:** 允许独立部署,由于模块是动态加载的,对应用程序的更改不需要重新部署整个应用。 4. **热模块替换:** 可以在不刷新页面的情况下替换模块。 ### 知识点四:Yarn 和 npm 包管理器 Yarn 和 npm 是 JavaScript 社区中最流行的两个包管理器,它们用于安装、更新和管理项目依赖。 #### Yarn: 1. **速度:** Yarn 在安装依赖时具有更快的速度。 2. **确定性:** 通过使用 lock 文件确保依赖安装的一致性。 3. **离线缓存:** Yarn 缓存了安装的每个包,以便在离线模式下工作。 #### npm: 1. **广泛性:** npm 是 JavaScript 社区中最广泛使用的包管理器。 2. **生态系统:** npm 拥有一个庞大且活跃的生态系统,提供了大量可用的包。 ### 知识点五:monorepo Monorepo 是一种源代码管理策略,其中所有项目代码都位于同一个仓库中。与多仓库(每个项目一个仓库)相反,monorepo 管理方式可以在整个项目的上下文中共享和管理代码。 #### monorepo 的优势: 1. **代码共享:** 项目之间可以共享代码库,便于代码复用。 2. **集中管理:** 统一的依赖管理和版本控制。 3. **项目间依赖清晰:** 项目间依赖关系透明,便于维护和开发。 ### 知识点六:工作区(Workspaces) 工作区是 monorepo 的一个重要组成部分,它允许一个仓库中包含多个包或项目。每个工作区可以有自己的 `package.json` 和依赖项,并且可以互相引用,简化了复杂项目的依赖管理。 #### 工作区特点: 1. **依赖管理:** 允许工作区依赖于仓库中的其他包。 2. **扁平化依赖:** 可以确保依赖项只被安装一次,节省了空间并减少了重复。 3. **开发流程简化:** 工作区设置简化了开发流程,允许同时工作在多个项目或包上。 ### 实际操作指令解读 1. **初始化项目:** - `yarn install` 或 `npm install`:安装依赖,根据仓库设置的不同可能包括 Lerna 或其他依赖。 2. **开发模式:** - `yarn develop` 或 `npm run develop`:启动开发服务器,对于带有预览的情况,可以使用 `WITH_PREVIEWS=1 yarn develop`。 3. **构建和启动单个远程生产版本:** - `yarn clean` 清除之前的构建。 - `yarn single:build` 单独构建生产版本。 - `yarn single:start` 启动生产服务器。 4. **构建和启动多个远程生产版本:** - `yarn multi:build` 构建多个生产版本。 - `yarn multi:start` 启动多版本生产服务器。 5. **构建镜像:** - `yarn docker:build` 使用 Yarn 构建 Docker 镜像。 以上操作指令展示了如何在使用 Lerna 和 Module Federation 的微前端 monorepo 环境下进行项目的初始化、开发、构建和部署,使用 Yarn 和 npm 工作区来优化多项目依赖管理与构建流程。
recommend-type

RHCSA实践考试及相关知识汇总

# RHCSA 实践考试及相关知识汇总 ## 一、实践考试说明 ### (一)通用注意事项 为确保考试在干净的环境中开始,需遵循以下提示: - 无需任何外部服务器或资源。 - 不要注册或连接任何外部存储库。 - 根据每个实践考试的说明安装新的虚拟机。 - 这些实践考试不提供示例解决方案,在实际考试中,你需要能够自行验证解决方案。 - 应能在两小时内完成每个考试。 ### (二)实践考试 C 内容 1. **安装虚拟机**:安装一个 RHEL 8 或 CentOS 8 虚拟机,要求如下: - 2GB 内存。 - 使用默认分区,20GB 磁盘空间。 - 一个额外的 20