我正在尝试使用带有超声波传感器的python来测量距离,然后每秒用距离值更新tkinter标签。但是,我遇到了问题。它会运行一段时间,从几秒钟到几分钟不等,然后冻结。
这是我的代码:
from tkinter import *
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO_TRIGGER_X = 4
GPIO_ECHO_X = 27
GPIO.setup(GPIO_TRIGGER_X, GPIO.OUT)
GPIO.setup(GPIO_ECHO_X, GPIO.IN)
def distanceX():
GPIO.output(GPIO_TRIGGER_X, True)
time.sleep(0.0001)
GPIO.output(GPIO_TRIGGER_X, False)
StartTime = time.time()
StopTime = time.time()
while GPIO.input(GPIO_ECHO_X) == 0:
StartTime = time.time()
while GPIO.input(GPIO_ECHO_X) == 1:
StopTime = time.time()
TimeElapsed = StopTime - StartTime
distance = (TimeElapsed * 34300) / 2
return distance
def updateDistance():
dX = distanceX()
print(dX)
lengthValue.configure(text=dX)
root.after(1000, updateDistance)
root = Tk()
root.geometry("200x100")
root.tk_setPalette(background="white", foreground="black")
lengthName = Label(root, text = "Length:")
lengthValue = Label(root, text="start")
lengthName.grid(row=1, column=1)
lengthValue.grid(row=1, column=2)
updateDistance()
root.mainloop()
我尝试在单独的脚本中单独运行distanceX()
,仅打印出值,效果很好。我也尝试过在没有distanceX()
的情况下运行脚本,如下所示:
dX = 0
def updateDistance():
global dX
print(dX)
lengthValue.configure(text=dX)
dX += 1
root.after(1000, updateDistance)
..也可以正常工作。
有什么想法吗? 如果我没有提供任何必要的信息,请提前道歉,这是我第一次尝试使用python和tkinter ...
答案 0 :(得分:0)
Tkinter是单线程的。您在函数<?php
header("Location: http://localhost/Rocket/includes/thankYou.php");
include('connection.php');
if(isset($_POST['addForm'])) {
$fullName = $_POST['fullName'];
$email = $_POST['email'];
$mobile = $_POST['mobile'];
$dob = $_POST['dob'];
$degree = $_POST['degree'];
$expYears = $_POST['expYears'];
$position = $_POST['jobPosition'];
$whyHire = $_POST['whyHire'];
$uploadCV = $_POST['uploadCV'];
$dateApplied = $_POST['dateApplied'];
$db = new Database();
$db->connect();
$db->insert('users',array('fullName'=>$fullName,'email'=>$email, 'mobile'=>$mobile,
'dob'=>$dob, 'degree'=>$degree, 'expYears'=>$expYears, 'position'=>$position,
'whyHire'=>$whyHire, 'uploadCV'=>$uploadCV, 'dateApplied'=>$dateApplied)); // Table name, column names and respective values
$res = $db->getResult();
print_r($res);
if($res) {
echo "Sent to DB";
die();
} else {
echo "query error";
}
}
中的while循环将阻塞主线程,直到它接收到True值并继续执行该函数的其余部分为止。这就是为什么您遇到冻结的原因。
尝试运行以下内容:
distanceX
您将看到由于While循环阻塞了主线程,您的Tk窗口甚至没有弹出。
要解决此问题,您需要对from tkinter import *
import time
root = Tk()
flag = True
def something():
global flag
while flag:
print ("Hello World")
time.sleep(1)
def set_flag():
global flag
flag = False
something()
root.after(2000,set_flag)
root.mainloop()
函数进行线程化。像这样:
distanceX()
您可以在here中阅读有关线程的更多信息。
答案 1 :(得分:0)
发现问题实际上是while
中的两个distanceX()
循环。都添加了超时,一切都很好。工作代码:
from tkinter import *
import RPi.GPIO as GPIO
import threading, time
GPIO.setmode(GPIO.BCM)
GPIO_TRIGGER_X = 4
GPIO_ECHO_X = 27
GPIO.setup(GPIO_TRIGGER_X, GPIO.OUT)
GPIO.setup(GPIO_ECHO_X, GPIO.IN)
def distanceX():
while True:
timeout = time.time() + 0.1
GPIO.output(GPIO_TRIGGER_X, True)
time.sleep(0.0001)
GPIO.output(GPIO_TRIGGER_X, False)
StartTime = time.time()
StopTime = time.time()
while GPIO.input(GPIO_ECHO_X) == 0:
StartTime = time.time()
if time.time() > timeout:
break
while GPIO.input(GPIO_ECHO_X) == 1:
StopTime = time.time()
if time.time() > timeout:
break
TimeElapsed = StopTime - StartTime
distance = (TimeElapsed * 34300) / 2
print(distance)
lengthValue.configure(text=distance)
time.sleep(1)
def check():
print("All good")
root = Tk()
root.geometry("200x100")
root.tk_setPalette(background="white", foreground="black")
lengthName = Label(root, text = "Length:")
lengthValue = Label(root, text="start")
button = Button(root, text="Check", command=check)
lengthName.grid(row=1, column=1)
lengthValue.grid(row=1, column=2)
button.grid(row=2, column=1)
t1 = threading.Thread(target=distanceX)
t1.start()
root.mainloop()