有没有办法同时进行下载过程和Tkinter图形界面工作?

huangapple go评论115阅读模式
英文:

Is there any solution to make work downloading process and tkinter gui at same time

问题

Here's the translated code for the provided Python code. I've excluded the code comments:

  1. def download_sniffers_data(self, date_start, date_end, sniffers_list, gui):
  2. ftp = FTP
  3. is_date_found = False
  4. ip_address = x
  5. user_id = x
  6. psswd = x
  7. self.gui = gui
  8. try:
  9. ftp = FTP(ip_address)
  10. ftp.login(user=user_id, passwd=psswd)
  11. dir_names = ftp.nlst()
  12. print('connecting to server')
  13. if not os.path.isdir(os.getcwd() + '/output'):
  14. os.mkdir(os.getcwd() + '/output')
  15. output_dir_name = self.make_date_dir()
  16. for s in sniffers_list:
  17. print(f'searching for sniffer "{s}"')
  18. self.gui.change_lbl()
  19. if s in dir_names:
  20. ftp.cwd('/' + s + '/backup')
  21. folders_list = ftp.nlst()
  22. for folder in folders_list:
  23. try:
  24. date_temp = datetime.strptime(f'{folder[4: 6]}/{folder[2: 4]}/{folder[0:2]}',
  25. '%d/%m/%y')
  26. if date_start.date() <= date_temp.date() <= date_end.date():
  27. ftp.cwd('/' + s + '/backup' + '/' + folder)
  28. files_list = ftp.nlst()
  29. print('searching for files')
  30. for file in files_list:
  31. try:
  32. file_array = file.split('-')
  33. string1 = f'{file_array[1][-2:]}.{file_array[1][2:4]}.{file_array[1][:2]} {file_array[2][:2]}:{file_array[2][2:]}';
  34. date_file = datetime.strptime(string1, '%d.%m.%y %H:%M')
  35. if date_start <= date_file <= date_end:
  36. is_date_found = True
  37. print(f'downloading file {file}')
  38. path = os.getcwd() + '/dir_output' + '/' + output_dir_name + '/' + 'S' + s.strip('sni')
  39. if not os.path.isdir(path):
  40. os.mkdir(path)
  41. if not os.path.isfile(f'{path}/{file}'):
  42. with open(f'{path}/{file}', 'wb') as localfile:
  43. ftp.retrbinary(f'RETR {file}', localfile.write, 1024)
  44. except ValueError:
  45. pass
  46. except ValueError:
  47. pass
  48. if not is_date_found:
  49. self.data_not_found_msgs.append(f'sniffer number: "{s}" no data found between the specified dates')
  50. is_date_found = False
  51. else:
  52. self.data_not_found_msgs.append(f'sniffer number: "{s}" not found in the server')
  53. gui.change_lbl()
  54. except ConnectionError:
  55. print('unable to connect to server')
  56. exit()
  57. except FileNotFoundError:
  58. print('file not found')
  59. exit()
  60. except ftplib.all_errors:
  61. print('FTP connection error')
  62. exit()
  63. finally:
  64. for msg in self.data_not_found_msgs:
  65. print(msg)
  66. ftp.close()
  67. class App(customtkinter.CTk):
  68. def __init__(self, snidatadl, date_start, date_end, sniffers_list):
  69. super().__init__()
  70. self.lbl_download = customtkinter.CTkLabel(master=self, font=("Helvetica", 16), text="")
  71. self.geometry("600x500")
  72. self.title("StaMes GUI")
  73. self.snidatadl = snidatadl
  74. self.date_start = date_start
  75. self.date_end = date_end
  76. self.sniffers_list = sniffers_list
  77. self.create_widgets()
  78. def create_widgets(self):
  79. # DATE FROM
  80. decotarion1_label = customtkinter.CTkLabel(master=self, text="FROM: ", font=("Helvetica", 16))
  81. decotarion1_label.place(x=100, y=50)
  82. date1_label = customtkinter.CTkLabel(master=self, text=self.date_start)
  83. date1_label.place(x=160, y=50)
  84. # DATE TO
  85. decotarion2_label = customtkinter.CTkLabel(master=this, text="TO: ", font=("Helvetica", 16))
  86. decotarion2_label.place(x=350, y=50)
  87. date2_label = customtkinter.CTkLabel(master=this, text=self.date_end)
  88. date2_label.place(x=380, y=50)
  89. # TABLE SNIFFERS
  90. scrollable_frame = customtkinter.CTkScrollableFrame(master=self, width=400, height=300)
  91. scrollable_frame.place(x=80, y=100)
  92. i = 0
  93. for x in self.sniffers_list:
  94. print(x)
  95. name = customtkinter.CTkLabel(master=scrollable_frame, text=x)
  96. name.grid(row=i, column=0, padx=20)
  97. i = i + 1
  98. # BUTTON
  99. run_btn = customtkinter.CTkButton(master=self, text="RUN", command=lambda: self.run())
  100. run_btn.place(x=350, y=420)
  101. # LABEL
  102. self.lbl_download.place(x=100, y=420)
  103. def run(self):
  104. threading.Thread(target= self.snidatadl.download_sniffers_data(self.date_start, self.date_end, self.sniffers_list, self))
  105. def change_lbl(self):
  106. self.lbl_download.configure(text="DOWNLOADING...")
英文:

I have a method like this, to download some info from an FTP server:

  1. def download_sniffers_data(self, date_start, date_end, sniffers_list, gui):
  2. ftp = FTP
  3. is_date_found = False
  4. ip_address = x
  5. user_id = x
  6. psswd = x
  7. self.gui = gui
  8. try:
  9. ftp = FTP(ip_address)
  10. ftp.login(user=user_id, passwd=psswd)
  11. dir_names = ftp.nlst()
  12. print(&#39;connecting to server&#39;)
  13. &quot;&quot;&quot;
  14. if not os.path.isdir(os.getcwd() + &#39;/output&#39;):
  15. os.mkdir(os.getcwd() + &#39;/output&#39;)
  16. &quot;&quot;&quot;
  17. output_dir_name = self.make_date_dir()
  18. for s in sniffers_list:
  19. print(f&#39;searching for sniffer &quot;{s}&quot;&#39;)
  20. self.gui.change_lbl()
  21. if s in dir_names:
  22. ftp.cwd(&#39;/&#39; + s + &#39;/backup&#39;)
  23. folders_list = ftp.nlst()
  24. for folder in folders_list:
  25. try:
  26. date_temp = datetime.strptime(f&#39;{folder[4: 6]}/{folder[2: 4]}/{folder[0:2]}&#39;,
  27. &#39;%d/%m/%y&#39;)
  28. if date_start.date() &lt;= date_temp.date() &lt;= date_end.date():
  29. ftp.cwd(&#39;/&#39; + s + &#39;/backup&#39; + &#39;/&#39; + folder)
  30. files_list = ftp.nlst()
  31. print(&#39;searching for files&#39;)
  32. for file in files_list:
  33. try:
  34. file_array = file.split(&#39;-&#39;)
  35. string1 = f&#39;{file_array[1][-2:]}.{file_array[1][2:4]}.{file_array[1][:2]} {file_array[2][:2]}:{file_array[2][2:]}&#39;
  36. date_file = datetime.strptime(string1, &#39;%d.%m.%y %H:%M&#39;)
  37. if date_start &lt;= date_file &lt;= date_end:
  38. is_date_found = True
  39. print(f&#39;downloading file {file}&#39;)
  40. path = os.getcwd() + &#39;/dir_output&#39; + &#39;/&#39; + output_dir_name + &#39;/&#39; + &#39;S&#39; + s.strip(
  41. &#39;sni&#39;)
  42. if not os.path.isdir(path):
  43. os.mkdir(path)
  44. if not os.path.isfile(f&#39;{path}/{file}&#39;):
  45. with open(f&#39;{path}/{file}&#39;, &#39;wb&#39;) as localfile:
  46. ftp.retrbinary(f&#39;RETR {file}&#39;, localfile.write, 1024)
  47. except ValueError:
  48. pass
  49. except ValueError:
  50. pass
  51. if not is_date_found:
  52. self.data_not_found_msgs.append(
  53. f&#39;sniffer number: &quot;{s}&quot; no data found between the specified dates&#39;)
  54. is_date_found = False
  55. else:
  56. self.data_not_found_msgs.append(f&#39;sniffer number: &quot;{s}&quot; not found in the server&#39;)
  57. gui.change_lbl()
  58. except ConnectionError:
  59. print(&#39;unable to connect to server&#39;)
  60. exit()
  61. &quot;&quot;&quot;
  62. &quot;&quot;&quot;&quot;&quot;&quot;
  63. except FileNotFoundError:
  64. print(&#39;file not found&#39;)
  65. exit()
  66. &quot;&quot;&quot;
  67. &quot;&quot;&quot;&quot;
  68. except ftplib.all_errors:
  69. print(&#39;FTP connection error&#39;)
  70. exit()
  71. &quot;&quot;&quot;
  72. finally:
  73. for msg in self.data_not_found_msgs:
  74. print(msg)
  75. ftp.close()

And a simple GUI:

  1. class App(customtkinter.CTk):
  2. def __init__(self, snidatadl, date_start, date_end, sniffers_list):
  3. super().__init__()
  4. self.lbl_download = customtkinter.CTkLabel(master=self, font=(&quot;Helvetica&quot;, 16), text=&quot;&quot;)
  5. self.geometry(&quot;600x500&quot;)
  6. self.title(&quot;StaMes GUI&quot;)
  7. self.snidatadl = snidatadl
  8. self.date_start = date_start
  9. self.date_end = date_end
  10. self.sniffers_list = sniffers_list
  11. self.create_widgets()
  12. def create_widgets(self):
  13. # DATE FROM
  14. decotarion1_label = customtkinter.CTkLabel(master=self, text=&quot;FROM: &quot;, font=(&quot;Helvetica&quot;, 16))
  15. decotarion1_label.place(x=100, y=50)
  16. date1_label = customtkinter.CTkLabel(master=self, text=self.date_start)
  17. date1_label.place(x=160, y=50)
  18. # DATE TO
  19. decotarion2_label = customtkinter.CTkLabel(master=self, text=&quot;TO: &quot;, font=(&quot;Helvetica&quot;, 16))
  20. decotarion2_label.place(x=350, y=50)
  21. date2_label = customtkinter.CTkLabel(master=self, text=self.date_end)
  22. date2_label.place(x=380, y=50)
  23. # TABLE SNIFFERS
  24. scrollable_frame = customtkinter.CTkScrollableFrame(master=self, width=400, height=300)
  25. scrollable_frame.place(x=80, y=100)
  26. i = 0
  27. for x in self.sniffers_list:
  28. print(x)
  29. name = customtkinter.CTkLabel(master=scrollable_frame, text=x)
  30. name.grid(row=i, column=0, padx=20)
  31. i = i + 1
  32. # BUTTON
  33. run_btn = customtkinter.CTkButton(master=self, text=&quot;RUN&quot;, command=lambda: self.run())
  34. run_btn.place(x=350, y=420)
  35. # LABEL
  36. self.lbl_download.place(x=100, y=420)
  37. def run(self):
  38. threading.Thread(target= self.snidatadl.download_sniffers_data(self.date_start, self.date_end, self.sniffers_list, self))
  39. def change_lbl(self):
  40. self.lbl_download.configure(text=&quot;DOWNLOADING...&quot;)

The idea, is to click on the button "RUN" and call the fuction to download some info, but I need to update the GUI while is running the download.

I have already try the asyncio, and i read about threading, which you think it could be the better idea to fix it?
I already try it with a minimal reproducible project, but still not working.

有没有办法同时进行下载过程和Tkinter图形界面工作?

答案1

得分: -1

我用一句话修复了它。
在调用change_lbl()方法之后添加self.gui.update()。

英文:

I fixed it with 1 sentence.
Adding

  1. self.gui.update()

after calling the method change_lbl()

huangapple
  • 本文由 发表于 2023年4月4日 18:03:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75928074.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定