树莓派python交互界面实例_树莓派综合项目2:智能小车(二)tkinter图形界面控制...
一、介紹
樹莓派綜合項目2:智能小車(一)四輪驅動中,實現了代碼輸入對四個電機的簡單控制,本章將使用Python 的圖形開發界面的庫——Tkinter 模塊(Tk 接口),編寫本地運行的圖形界面,控制小車的前進后退、轉向和原地轉圈。
Tkinter是Python的標準GUI庫,Python使用Tkinter可以快速的創建 GUI 應用程序。由于 Tkinter 是內置到 python 的安裝包中、只要安裝好 Python 之后就能 import Tkinter 庫、而且 IDLE 也是用 Tkinter 編寫而成、對于簡單的圖形界面 Tkinter 還是能應付自如。
其它基礎內容會在文集:樹莓派基礎實驗當中講解。
二、組件
★Raspberry Pi 3主板*1
★樹莓派電源*1
★40P軟排線*1
★L298N擴展板模塊*1
★智能小車底板模塊*1
★減速電機和車輪*4
★面包板*1
★跳線若干
三、實驗原理
擴展板供電接法
(一)常見的圖形開發界面的庫
Python 提供了多個圖形開發界面的庫,幾個常用 Python GUI 庫如下:
Tkinter: Tkinter 模塊(Tk 接口)是 Python 的標準 Tk GUI 工具包的接口 .Tk 和 Tkinter 可以在大多數的 Unix 平臺下使用,同樣可以應用在 Windows 和 Macintosh 系統里。Tk8.0 的后續版本可以實現本地窗口風格,并良好地運行在絕大多數平臺中。
wxPython:wxPython 是一款開源軟件,是 Python 語言的一套優秀的 GUI 圖形庫,允許 Python 程序員很方便的創建完整的、功能健全的 GUI 用戶界面。
PyQt:PyQt 是 Python 編程語言和 Qt 庫的成功融合。Qt 本身是一個擴展的 C++ GUI 應用開發框架,Qt 可以在 UNIX、Windows 和 Mac OS X 上完美運行,因此 PyQt 是建立在 Qt 基礎上的 Python 包裝。所以 PyQt 也能跨平臺使用。
(二)tk初始
注意:Python3.x 版本使用的庫名為 tkinter,即首寫字母 T 為小寫。
import tkinter
創建一個GUI程序
1、導入 Tkinter 模塊
2、創建控件
3、指定這個控件的 master, 即這個控件屬于哪一個
4、告訴 GM(geometry manager) 有一個控件產生了。
實例(Python3.x):
#!/usr/bin/python3
import tkinter
top = tkinter.Tk()
# 進入消息循環
top.mainloop()
實例(Python2.x):
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import Tkinter
top = Tkinter.Tk()
# 進入消息循環
top.mainloop()
以上代碼執行結果如下圖:
(三)創建基本窗口
#創建基本窗口
import tkinter as tk # 將tkinter導入到工程中
window = tk.Tk() # 創建窗體對象
window.title('musicplay') # 設置窗口標題
window.geometry('380x390') # 設置窗口大小,注意這里的x是英文字母x
#如果需要規定窗體打開的位置,可以在在380x390后面加上“+10+10”,
# 即橫坐標為10,縱坐標為10 的位置
window.resizable(0,0) # 如果不想人為修改窗體的大小,可以加上這個
#window.iconbitmap('./logo.ico') # 設置窗體圖標
#window.withdraw() # 隱藏窗口
#window.deiconify() # 顯示窗口
window.mainloop() # 調用mainloop方法,使窗體一直執行下去
以上代碼執行結果如下圖:
那么在tkinter中又有哪些控件可以供我們使用呢?
tkinter控件表
本實驗中只需要學會3種控件:標簽控件來顯示文字,按鈕控件來控制方向,范圍控件來控制油門。有點編程基礎的同學幾個小時就可以學會!
圖形界面
(四)Label標簽的使用
#設置標簽的大小和字體
import tkinter as tk
window = tk.Tk()
window.title('Label的使用')
window.geometry('400x400')
label = tk.Label(window,text='我是一個標簽', #text為顯示的文本內容
bg='black',fg='white', #bg為背景色,fg為前景色
font=("華文行楷", 20), #設置字體為“華文行楷”,大小為20
width=20,height=3) #width為標簽的寬,height為高
label.pack()
window.mainloop()
以上代碼執行結果如下圖:
label
#標簽里插入圖片,后面我們會用到按鈕里插入圖片
import tkinter as tk
window = tk.Tk()
window.title('Label的使用')
window.geometry('400x400')
photo = tk.PhotoImage(file='./up.png') #將圖片加載到窗口中
#注意加載進來的圖片只支持‘.gif’格式的圖片,如果是其他格式的文件可以用其他工具轉換一下,如PS、畫圖等
label2 = tk.Label(window,text='我是文字',
image=photo,
compound='center') #compound參數是指圖片和文字之間的關系
label.pack()
'''
anchor可用的值:
left: 圖像居左
right: 圖像居右
top: 圖像居上
bottom: 圖像居下
center: 文字覆蓋在圖像上
'''
window.mainloop()
以上代碼執行結果如下圖:
label_grahic
(五)Button按鍵的使用
#創建一個按鈕
#我們先創建一個寬20,長2,顯示文字為‘單擊’的按鈕練練手
import tkinter as tk
window = tk.Tk()
window.title("button")
window.geometry("300x180")
tk.Button(window,width=20,height=2,text='單擊').pack()
#如果后面我們需要對這個空間的屬性進行修改,或者進行信息的獲取,我們可以不指定對象,按鍵功能我們可以通過command參數實現
window.mainloop()
以上代碼執行結果如下圖:
button_1
#為按鍵添加一個回調函數
#現在我們已經將按鈕創建出來了,那么當按鈕按下去之后我們需要做些什么呢?這就需要設置command屬性,添加回調函數了
import tkinter as tk
window = tk.Tk()
window.title("button")
window.geometry("300x180")
def danji(): #這個就是我們寫的一個方法,下面由按鈕進行調用
print('hello') #當按鍵按下時,打印‘hello’
tk.Button(window,width=20,height=2,text='單擊',command=danji).pack()
#注意,在設置command屬性的時候,回調函數是不加'()'的,我們一般調用方法是需要,但這里就是設置屬性,不需要添加
window.mainloop()
以上代碼執行結果如下圖:
button_2
#在按鍵中放置圖片
#有些時候我們需要將界面做的更漂亮一點,我們可以像label一樣,用圖片來美化我們的按鈕
import tkinter as tk
window = tk.Tk()
photo = tk.PhotoImage(file='./up.png')
tk.Button(window, text='botton', compound='bottom', image=photo).pack()
tk.Button(window, text='top', compound='top', bitmap='error').pack()
#設置的相關屬性和Label類似,故這里就不做贅述了
window.mainloop()
以上代碼執行結果如下圖:
button_3
(六)Scale滑動條的使用
#比如Windows下的音量控制,音樂或者視頻的進度控制,
#都是用滑動條來實現的,本實驗中用來控制油門
from tkinter import *
window = Tk()
Scale(window,label='accelerator', #設置顯示的標簽
from_=0,to=100, # 設置最大最小值
#注意設置最大值的屬性不是'from',而是'from_',這是因為python中已經有了from關鍵字啦
resolution=1, # 設置步距值
orient=HORIZONTAL, # 設置水平方向
#如果我們想設置成垂直方向改怎么辦呢?直接缺省這個屬性就可以啦,默認就是垂直噠
).pack()
window.mainloop()
以上代碼執行結果如下圖:
scale_1
#綁定Scale的值為我們所用
from tkinter import *
window = Tk()
value = StringVar()
def s_print(text): #注意,Scale的回調函數需要給定形參,當觸發時會將Scale的值傳給函數
print(value.get())
print(text) #兩者同樣的效果
Scale(window,label='accelerator',
from_=0,to=100,
resolution=1,show=0,
variable=value,command=s_print
).pack()
window.mainloop()
以上代碼執行結果如下圖:
scale_2
(七)控件的定位
通過前面的文檔我們已經知道Tkinter控件的簡單使用,想要擁有一個簡潔、合理的界面,控件布局就顯得尤為重要了,而Tkinter提供了三種布局方式給我們。
1.pack是一種相對布局方式,指定控件的相對位置,精確位置會由系統完成。
pack布局沒有任何屬性參數,默認會自上而下垂直并且水平居中排列。我們可以通過side=TOP/BOTTOM/LEFT/RIGHT,控制控件的相對位置(上下左右),利用fill=x來是控件和窗體一樣寬,用padx、pady、ipadx、ipady控制控件的邊距。
from tkinter import *
window = Tk()
Label(window,text='first',bg='red').pack(fill=X,padx=10) #水平外邊距
Label(window,text='second',bg='green').pack(fill=X,pady=10) #垂直外邊距
Label(window,text='third',bg='yellow').pack(fill=X,ipadx=10) #水平內邊距
Button(window,text='fourth',bg='blue').pack(fill=X,ipady=10) #垂直內邊距
window.mainloop()
pack方式布局
2.grid布局我們可以理解成單元格布局方式,窗體就像是一個表格,橫向、縱向劃分了若干格子,我們將控件依次放入格子中進行定位。
from tkinter import *
window = Tk()
Label(window,text='first',bg='red').grid(row=1,column=1)
Label(window,text='second',bg='green').grid(row=1,column=3)
Label(window,text='third',bg='yellow').grid(row=2,column=2)
Button(window,text='fourth',bg='blue').grid(row=3,column=1)
window.mainloop()
grid布局方式
3.place布局是一種絕對位置布局方式,說的簡單點就是坐標定位方式,窗體最左上角的位置就是原點(x=0,y=0)。本實驗中我用的是這種方式。
from tkinter import *
window = Tk()
Label(window,text='first',bg='red').place(x=10,y=10)
Label(window,text='second',bg='green').place(x=10,y=40)
Label(window,text='third',bg='yellow').place(x=10,y=70)
Button(window,text='fourth',bg='blue').place(x=10,y=100)
window.mainloop()
place布局方式
四、實驗步驟
樹莓派(name)
樹莓派(BOARD)
L298N小車擴展板
GPIO.0
11
ENA
GPIO.2
13
IN1
GPIO.3
15
IN2
GPIO.1
12
ENB
GPIO.4
16
IN3
GPIO.5
18
IN4
GND
GND
電池組供電負極
關于這里樹莓派GND、L298N小車擴展板的電池組供電負極相連,是特殊情況下的情況,經測試發現:
如果樹莓派用的是充電頭供電,而L298N擴展板用的是電池組供電,這兩個負極必須相連,否則馬達不動。
如果樹莓派用的是L298N擴展板接出來的5V供電,即兩者同一個電源,則這里不用連接。
L298N小車擴展板
電池組
樹莓派
電壓表頭
馬達
電池+(-)
電池+(-)
5V供電
電源接口
+(-)
+(-)
T1(L后)
+(-)
T2(L前)
+(-)
T3(R前)
+(-)
T4(R后)
+(-)
剛開始時使用了面包板接線,GPIO使用的BCM模式,后來為了方便路面移動測試,讓樹莓派使用了多功能L298N智能小車擴展板上的5V供電,并且GPIO改用了BOARD模式。
智能小車四輪驅動電路圖
擴展板供電接法1
第2步: 編寫電機的驅動程序,文件名為motor_4w.py。與樹莓派綜合項目2:智能小車(一)四輪驅動中的程序完全相同。
該車的行進控制與履帶車的行進控制類似:
前進和后退很簡單,左右兩邊的方向都朝前或朝后,速度一致;
原地順時針旋轉時,左邊輪子前進,右邊輪子后退,速度一致;
原地逆時針旋轉時,左邊輪子后退,右邊輪子前進,速度一致;
偏左前進時,左右兩邊的方向都朝前,左輪速度比右輪速度慢一點;
偏右前進時,左右兩邊的方向都朝前,左輪速度比右輪速度快一點;
偏左后退時,左右兩邊的方向都朝后,左輪速度比右輪速度慢一點;
偏右后退時,左右兩邊的方向都朝后,左輪速度比右輪速度快一點;
motor_4w.py:
#!/usr/bin/env python
import RPi.GPIO as GPIO
class SMPcar:
'''控制小車四輪動作的類'''
ENA = 11 #使能信號A,左邊兩輪
IN1 = 13 #信號輸入1
IN2 = 15 #信號輸入2
ENB = 12 #使能信號B,右邊兩輪
IN3 = 16 #信號輸入3
IN4 = 18 #信號輸入4
GPIO.setwarnings(False) #關閉警告
def setGPIO(self):
'''初始化引腳'''
GPIO.setmode(GPIO.BOARD)
GPIO.setup(SMPcar.ENA, GPIO.OUT)
GPIO.setup(SMPcar.IN1, GPIO.OUT)
GPIO.setup(SMPcar.IN2, GPIO.OUT)
GPIO.setup(SMPcar.ENB, GPIO.OUT)
GPIO.setup(SMPcar.IN3, GPIO.OUT)
GPIO.setup(SMPcar.IN4, GPIO.OUT)
def pwm(self,pwm):
'''初始化PWM(脈寬調制),返回PWM對象'''
EN_pwm = GPIO.PWM(pwm, 500)
EN_pwm.start(0)
return EN_pwm
def changespeed(self,pwm,speed):
'''通過脈寬調制改變占空比改變馬達轉速'''
pwm.ChangeDutyCycle(speed)
def clockwise(self,in1_pin,in2_pin):
'''馬達順時針轉的信號
若電機旋轉方向不正確,交換電機的正負極'''
GPIO.output(in1_pin, 1)
GPIO.output(in2_pin, 0)
def counter_clockwise(self,in1_pin,in2_pin):
'''馬達逆時針轉的信號'''
GPIO.output(in1_pin, 0)
GPIO.output(in2_pin, 1)
def stop_car(self,in1_pin,in2_pin):
'''馬達制動的信號
使能信號為低電平,或者高電平(占空比設為100,
IN1和IN2都為0或1時)馬達制動'''
GPIO.output(in1_pin, 0)
GPIO.output(in2_pin, 0)
def destroy(self,A,B):
'''結束程序時清空GPIO狀態,
若不清空狀態,再次運行時會有警告'''
A.stop()
B.stop()
GPIO.cleanup() # Release resource
if __name__ == '__main__': # Program start from here
try:
smpcar = SMPcar() #創建樹莓派小車對象
smpcar.setGPIO() #初始化引腳
ENA_pwm=smpcar.pwm(smpcar.ENA) #初始化使能信號PWM,ENA為左邊車輪
ENB_pwm=smpcar.pwm(smpcar.ENB) #初始化使能信號PWM,ENB為右邊車輪
while True:
'''通過輸入的命令改變馬達轉動
這里是考慮到后期,遠程控制也是發送控制代碼實現控制,
這里采用這種方式也很方便'''
cmd = input("Command, E.g. ff30ff30 :")
direction = cmd[0] #只輸入字母b時,小車剎車
A_direction = cmd[0:2] #字符串0/1兩位為控制A(左邊車輪)方向信號
B_direction = cmd[4:6] #4/5位為控制B(右邊車輪)方向信號
A_speed = cmd[2:4] #字符串2/3兩位為控制A(左邊車輪占空比)速度信號
B_speed = cmd[6:8] #字符串6/7兩位為控制B(右邊車輪占空比)速度信號
print (A_direction,B_direction,A_speed,B_speed) #測試用
if A_direction == "ff": #控制A(左邊車輪)順時針信號
smpcar.clockwise(smpcar.IN1,smpcar.IN2)
if A_direction == "00": #控制A(左邊車輪)逆時針信號
smpcar.counter_clockwise(smpcar.IN1,smpcar.IN2)
if B_direction == "ff": #控制B(右邊車輪)順時針信號
smpcar.clockwise(smpcar.IN3,smpcar.IN4)
if B_direction == "00": #控制B(右邊車輪)逆時針信號
smpcar.counter_clockwise(smpcar.IN3,smpcar.IN4)
if direction == "b": #小車剎車,IN1和IN2都為0,馬達制動
smpcar.stop_car(smpcar.IN1,smpcar.IN2)
smpcar.stop_car(smpcar.IN3,smpcar.IN4)
continue #跳出本次循環
# 通過輸入的兩位數字設置占空比,改變馬達轉速
smpcar.changespeed(ENA_pwm,int(A_speed))
smpcar.changespeed(ENB_pwm,int(B_speed))
except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
smpcar.destroy(ENA_pwm,ENB_pwm)
finally:
smpcar.destroy(ENA_pwm,ENB_pwm)
第3步: 編寫圖形控制界面,文件名為gui_motor_4w.py。界面控件一個個的添加和調試,每個控件的回調函數一個個調試,最終全部成功。先點擊方向按鈕,再滑動油門,小車行進;也可以先設定好油門,再點擊方向按鈕,小車行進。將這兩個文件放進一個文件夾,只運行gui_motor_4w.py即可。
圖形界面
上中和下中按鈕為前進和后退,中左和中右為原地左轉和原地右轉,四個角上的按鈕為向左、向右、向左后、向右后偏向行進,正中間的黑色暫停按鈕為剎車和方向復位鍵。
gui_motor_4w.py:
from tkinter import * # 將tkinter導入到工程中
import motor_4w
'''acc_left為左邊車輪油門的中間參數,
用于轉向時,減低左輪的油門值,形成左右速差'''
acc_left = 0
acc_right = 0 #右邊車輪油門的中間參數
smpcar = motor_4w.SMPcar()
smpcar.setGPIO() #初始化引腳
ENA_pwm=smpcar.pwm(smpcar.ENA) #初始化PWM(脈寬調制)
ENB_pwm=smpcar.pwm(smpcar.ENB)
root = Tk() # 創建窗體對象
root.wm_title('4w_motor Control') # 設置窗口標題
curWidth = 1050 #窗口寬度
curHight = 450 #窗口度
# 獲取屏幕寬度和高度
scn_w, scn_h = root.maxsize()
#print(scn_w, scn_h)
# 計算中心坐標
cen_x = (scn_w - curWidth) / 2
cen_y = (scn_h - curHight) / 2
#print(cen_x, cen_y)
# 設置窗口初始大小和位置
size_xy = '%dx%d+%d+%d' % (curWidth, curHight, cen_x, cen_y) # 注意這里的x是英文字母x
root.geometry(size_xy) # 設置窗口大小
def leftTurn():
'''原地左轉彎'''
acc_value = scale_accelerator.get() #獲取油門值
smpcar.counter_clockwise(smpcar.IN1,smpcar.IN2) #左邊車輪后退
smpcar.clockwise(smpcar.IN3,smpcar.IN4) #右邊車輪前進
smpcar.changespeed(ENA_pwm,(acc_value)) #根據剛獲取的油門值調整速度
smpcar.changespeed(ENB_pwm,(acc_value))
def rightTurn():
'''原地右轉彎'''
acc_value = scale_accelerator.get()
smpcar.clockwise(smpcar.IN1,smpcar.IN2)
smpcar.counter_clockwise(smpcar.IN3,smpcar.IN4)
smpcar.changespeed(ENA_pwm,(acc_value))
smpcar.changespeed(ENB_pwm,(acc_value))
def forward():
'''直線前進'''
acc_value = scale_accelerator.get()
smpcar.clockwise(smpcar.IN1,smpcar.IN2)
smpcar.clockwise(smpcar.IN3,smpcar.IN4)
smpcar.changespeed(ENA_pwm,(acc_value))
smpcar.changespeed(ENB_pwm,(acc_value))
def reverse():
'''直線后退'''
acc_value = scale_accelerator.get()
smpcar.counter_clockwise(smpcar.IN1,smpcar.IN2)
smpcar.counter_clockwise(smpcar.IN3,smpcar.IN4)
smpcar.changespeed(ENA_pwm,(acc_value))
smpcar.changespeed(ENB_pwm,(acc_value))
def brake():
'''剎車'''
smpcar.stop_car(smpcar.IN1,smpcar.IN2)
smpcar.stop_car(smpcar.IN3,smpcar.IN4)
global acc_left
global acc_right
acc_left = 0 #左邊車輪油門清零
acc_right = 0 #右邊車輪油門清零
'''定義前進、后退、原地左轉、原地右轉、剎車插圖的對象'''
up_im = PhotoImage(file='./up.png')
down_im = PhotoImage(file='./down.png')
left_im = PhotoImage(file='./left.png')
right_im = PhotoImage(file='./right.png')
brake_im = PhotoImage(file='./brake.png')
'''定義按鈕'''
Button(root, text='forward',bd=10,image=up_im,command=forward).place(x=230,y=70) #定義前進按鈕
Button(root, text='reverse',bd=10,image=down_im,command=reverse).place(x=230,y=330) #定義后退按鈕
Button(root, text='left',bd=10,image=left_im,command=leftTurn).place(x=110,y=200) #定義原地左轉按鈕
Button(root, text='right',bd=10,image=right_im,command=rightTurn).place(x=350,y=200) #定義原地右轉按鈕
Button(root, text='brake',bd=10,image=brake_im,command=brake).place(x=230,y=200) #定義剎車按鈕
a=0
'''a為中間參數,用于左前和左后按鈕切換時,清零參數acc_left'''
def forward_left():
'''朝左前方轉向行進'''
global a
global acc_left
if a == 0: #表明調用該函數前,已點擊了 左后 按鈕
acc_left = 0 #清零參數acc_left
a += 1 #點擊 左前 按鈕后,a會一定大于0
acc_value = scale_accelerator.get() #獲取油門值
'''forward_left()函數被調用一次,參數acc_left累減5'''
acc_left -= 5
global acc_right
acc_right = 0 #左轉時右輪參數acc_right清零
'''左輪的實際油門+參數acc_left得到左輪油門降低
而右輪不變的情況下,左輪慢,右輪快,車向左轉向前進'''
acc_value_left = acc_value + acc_left
if acc_value_left < 0: #防止點左轉次數過多
acc_value_left = 0
smpcar.clockwise(smpcar.IN1,smpcar.IN2) #車輪方向都向前行進
smpcar.clockwise(smpcar.IN3,smpcar.IN4)
smpcar.changespeed(ENA_pwm,acc_value_left)
smpcar.changespeed(ENB_pwm,acc_value)
b=0
'''b為中間參數,用于右前和右后按鈕切換時,清零參數acc_right'''
def forward_right():
'''朝右前方轉向行進'''
global b
global acc_right
if b == 0: #表明調用該函數前,已點擊了 右后 按鈕
acc_right = 0 #清零參數acc_right
b += 1 #點擊 右前 按鈕時,b會一定大于0
acc_value = scale_accelerator.get() #獲取油門值
'''forward_right()函數被調用一次,參數acc_right累減5'''
acc_right -= 5
global acc_left
acc_left = 0 #右轉時左輪參數acc_left清零
'''右輪的實際油門+參數acc_right得到右輪油門降低
而左輪不變的情況下,左輪快,右輪慢,車向右轉向前進'''
acc_value_right = acc_value + acc_right
if acc_value_right < 0:
acc_value_right = 0
smpcar.clockwise(smpcar.IN1,smpcar.IN2)
smpcar.clockwise(smpcar.IN3,smpcar.IN4)
smpcar.changespeed(ENA_pwm,acc_value)
smpcar.changespeed(ENB_pwm,acc_value_right)
def reverse_left():
'''朝左后方轉向倒車'''
global a
global acc_left
if a > 0: #表明調用該函數前,點擊了 左前 按鈕
acc_left = 0 #清零參數acc_left
a *= 0 #每點擊 左后 按鈕a就會置0
acc_value = scale_accelerator.get()
acc_left -= 5
global acc_right
acc_right = 0
acc_value_left = acc_value + acc_left
if acc_value_left < 0:
acc_value_left = 0
smpcar.counter_clockwise(smpcar.IN1,smpcar.IN2)
smpcar.counter_clockwise(smpcar.IN3,smpcar.IN4)
smpcar.changespeed(ENA_pwm,acc_value_left)
smpcar.changespeed(ENB_pwm,acc_value)
def reverse_right():
'''朝右后方轉向倒車'''
global b
global acc_right
if b > 0: #表明調用該函數前,點擊了 右前 按鈕
acc_right = 0 #清零參數acc_right
b *= 0 #每點擊 右后 按鈕b就會置0
acc_value = scale_accelerator.get()
acc_right -= 5
global acc_left
acc_left = 0
acc_value_right = acc_value + acc_right
if acc_value_right < 0:
acc_value_right = 0
smpcar.counter_clockwise(smpcar.IN1,smpcar.IN2)
smpcar.counter_clockwise(smpcar.IN3,smpcar.IN4)
smpcar.changespeed(ENA_pwm,acc_value)
smpcar.changespeed(ENB_pwm,acc_value_right)
'''定義左前、右前、左后、右后行進插圖的對象'''
up_left_im = PhotoImage(file='./up_left.png')
up_right_im = PhotoImage(file='./up_right.png')
down_left_im = PhotoImage(file='./down_left.png')
down_right_im = PhotoImage(file='./down_right.png')
Button(root, text='up_left',bd=10,image=up_left_im,command=forward_left).place(x=110,y=70) #定義向前偏左行進按鈕
Button(root, text='up_right',bd=10,image=up_right_im,command=forward_right).place(x=350,y=70) #定義向前偏右行進按鈕
Button(root, text='down_left',bd=10,image=down_left_im,command=reverse_left).place(x=110,y=330) #定義向后偏左行進按鈕
Button(root, text='down_right',bd=10,image=down_right_im,command=reverse_right).place(x=350,y=330) #定義向后偏右行進按鈕
'''定義標簽'''
label1 = Label(root,
text='Accelerator',
#bg='black',
fg='red',
font=("華文行楷", 20), #設置字體為“華文行楷”,大小為20
#width=9,height=3
)
label1.place(x=740,y=390)
'''根據scale滑動條的值,調整油門大小'''
def accelerator(v):
acc_value = int(v)
global acc_left
global acc_right
acc_value_left = acc_value + acc_left #加上中間參數
acc_value_right = acc_value + acc_right
if acc_value_left < 0:
acc_value_left = 0
if acc_value_right < 0:
acc_value_right = 0
smpcar.changespeed(ENA_pwm,acc_value_left)
smpcar.changespeed(ENB_pwm,acc_value_right)
'''定義scale滑動條'''
scale_accelerator = Scale(root,
#label='accelerator', # 設置顯示的標簽
from_=100, # 設置最大最小值
to=0,
resolution=2, # 設置步距值
orient=VERTICAL, #如果我們想設置成垂直方向改怎么辦呢?直接缺省這個屬性就可以啦,默認就是垂直
#show=0, # 隱藏滑動條的值
#variable=value_a, # 綁定Scale的值為我們所用
activebackground='red',
length=350,
width=30, # 設置Scale的寬度,默認是16。
sliderlength=50, # 滑塊的大小。默認值是30
bd=10, # 設置Scale控件邊框寬度
tickinterval=20, # 顯示刻度,并定義刻度的粒度
troughcolor='red', # 設置滑動槽的背景顏色
command=accelerator
)
scale_accelerator.place(x=720,y=0)
root.mainloop()
smpcar.destroy(ENA_pwm,ENB_pwm) #退出程序時,清空GPIO狀態
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的树莓派python交互界面实例_树莓派综合项目2:智能小车(二)tkinter图形界面控制...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《隐秘的角落》将翻拍日版电影
- 下一篇: Ruffle 开源项目:使用 Rust