【问题标题】:Tkinter button starts program after closing the main windowTkinter 按钮在关闭主窗口后启动程序
【发布时间】:2021-02-26 11:04:08
【问题描述】:

我正在尝试制作用于从 arduino 获取数据的 GUI。我想在按下按钮后输入文件名并开始数据采集。在我按下按钮的那一刻,什么都没有发生,但是当我关闭窗口时它开始了。我希望窗户保持打开状态。

我的代码如下:

import serial
from tkinter import *
import csv

def start_measurement():
    global file_name
    file_name = entry_1.get()

my_window = Tk()
label_1 = Label(my_window, text = "File name: ")
entry_1 = Entry(my_window)
button_1 = Button(my_window, text = "Save", command = start_measurement)

label_1.grid(row=0, column=0)
entry_1.grid(row=0, column=1)
button_1.grid(row=0, column=2)

my_window.mainloop()

arduinoData =serial.Serial('COM15', 9600)

while (True):
    while(arduinoData.inWaiting()==0):
        pass
    arduinoString = arduinoData.readline().decode().split(',')
    x=float(arduinoString[0])
    y=float(arduinoString[1])

    print(x, y)

    with open(file_name + '.csv', 'a', newline='') as f:
        writer = csv.writer(f, delimiter = ',')
        writer.writerow([x, y])
    f.close()

【问题讨论】:

  • 删除my_window.mainloop() 和内部while Truemy_window.update()。虽然最好在单独的线程中移动函数内部的逻辑,否则while 循环会阻塞mainloop()

标签: python tkinter button


【解决方案1】:

我的回答很简单。


首先让我提一下您在代码中遇到的问题:

  1. 如果您希望 gui 执行您希望它执行的功能,那么根据您的代码,整个代码应该在这两个语句中:
  • 第一个声明:my_window = Tk()
  • 第二个声明:my_window.mainloop()
  1. 您希望在单击按钮时程序执行。根据您的代码,按钮仅执行此操作,没有其他操作。
global file_name
file_name = entry_1.get()

现在为什么会这样?为什么它会在您的窗口关闭时执行?

这就是答案。正如我在1 错误中提到的,如果您希望它与窗口一起执行,则整个代码应该在里面。您的代码出现在 tkinter mainloop 之后,它将它从 gui 程序中排除。因此,在 gui 运行之前,mainloop 不会执行下面的代码行,当它关闭时循环结束,然后执行其余部分,因此您会遇到您提到的问题。


如何做你想做的事?

您希望在单击按钮时执行此代码,因此此代码应位于函数start_measurement() 中,因为这是按钮应该执行的操作。

arduinoData =serial.Serial('COM15', 9600)

while (True):
    while(arduinoData.inWaiting()==0):
        pass
    arduinoString = arduinoData.readline().decode().split(',')
    x=float(arduinoString[0])
    y=float(arduinoString[1])

    print(x, y)

    with open(file_name + '.csv', 'a', newline='') as f:
        writer = csv.writer(f, delimiter = ',')
        writer.writerow([x, y])
    f.close()

我会说从当前位置剪切这段代码,然后将其添加到start_measurement() 函数中。


现在,如果我进行更正并再次编写代码。那么这就是最终的结果。

import serial
from tkinter import *
import csv

def start_measurement():
    global file_name
    file_name = entry_1.get()
    arduinoData =serial.Serial('COM15', 9600)

    while (True):
        while(arduinoData.inWaiting()==0):
            pass
        arduinoString = arduinoData.readline().decode().split(',')
        x=float(arduinoString[0])
        y=float(arduinoString[1])

        print(x, y)

        with open(file_name + '.csv', 'a', newline='') as f:
            writer = csv.writer(f, delimiter = ',')
            writer.writerow([x, y])
        f.close()

my_window = Tk()
label_1 = Label(my_window, text = "File name: ")
entry_1 = Entry(my_window)
button_1 = Button(my_window, text = "Save", command = start_measurement)

label_1.grid(row=0, column=0)
entry_1.grid(row=0, column=1)
button_1.grid(row=0, column=2)

my_window.mainloop()

请试一试,并告诉我它是否有效,因为当我尝试它时,它工作得很好。如果您觉得这里有什么不明白的地方,请发表评论。

谢谢! :)

【讨论】:

  • 非常感谢您的清晰和逐步的解释。这非常有帮助。我测试了代码,当我按下按钮时它会保存数据。但是当程序运行时我注意到了一个小问题,我在窗口中的任意位置单击它表明停止响应。
  • 好吧,老实说,我没有任何答案,因为我在许多其他 GUI 程序中遇到了同样的问题。我从来没有找到一个可行的解决方案。对不起。
【解决方案2】:

在主循环之后你有实际的过程。这就是当您关闭程序时其余代码会启动的原因。您应该在 my_window.mainloop() 和函数中拥有所有内容。基本上,mainloop 是一个 while 循环,它不断更新 GUI 以适应变化,因此在它被破坏(窗口关闭)之前无法访问其余代码。

【讨论】:

  • 如果你能展示它是如何完成的就好了。
猜你喜欢
  • 2012-01-06
  • 2018-12-31
  • 1970-01-01
  • 1970-01-01
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-22
相关资源
最近更新 更多