Posts tagged ‘python’

How To Change The Label Font in TKinter

The font attribute of the label widget can be used to change the font style and size.

First, we will create a window with a label using the default font and size.

import tkinter as tk

win = tk.Tk()
win.geometry("750x450")

title_label = tk.Label(win, text="hello")
title_label.pack(pady=10)

win.mainloop()

Below is the window with the label’s default font and style.

Next, we will add the font attribute to the label widget to customize the font style and size. In this example, we are going to change the font style to “Impact” and the font size to 20. The possible font styles are listed on the page https://learn.microsoft.com/en-us/typography/font-list/.

import tkinter as tk

win = tk.Tk()
win.geometry("750x450")

title_label = tk.Label(win, text="hello", font= 'Impact 17')
title_label.pack(pady=10)


win.mainloop()

Below is the output with the label’s customized font style and size.

Displaying An Image With Python Tkinter

The aim of the tutorial is to display an image using Tkinter. The image will change when a button is pressed.

Step 1

Create the Tkinter window.

import tkinter as tk

win = tk.Tk()
win.geometry("750x450")

win.mainloop()

When executed the code should generate a window 750 by 450.

TK window

Step 2

Display the image in the window. The code will load the image into a variable called photo. The code then adds a Label to the window of the type image and populates the label with the photo. In this example, the image is called car-jump.gif and the python code will assume the image file is in the same directory as the python code.

import tkinter as tk

win = tk.Tk()
win.geometry("750x450")

photo = tk.PhotoImage(file='car-jump.gif')
image = tk.Label(win, image=photo)
image.pack()

win.mainloop()

When executed the code will create a window with an image.

Step 4

Add a button to the window. First, we are going to add a button to the window and confirm the button will print a message when clicked. In the next step, we will link the button to the image.

import tkinter as tk


def change_image():
    print("Button has been clicked")


win = tk.Tk()
win.geometry("750x450")

photo = tk.PhotoImage(file='car-jump.gif')
image = tk.Label(win, image=photo)
image.pack()

button = tk.Button(win, text="Click to change image", command=change_image)
button.pack()

win.mainloop()

When executed the window should show the image and a button.

Tk window with image and button

In the console window, you should see the message “Button has been clicked”, every time the button has been clicked.

Step 5

In this step we will add the code to the change_image function that will change the image from car to a flower. In this example, the code assumes the flower.gif file will be in the same folder as the python code.

import tkinter as tk


def change_image():
    global show_car, image
    filename = 'not set'
    if show_car:
        filename = 'car-jump.gif'
        show_car = False
    else:
        filename = 'flower.gif'
        show_car = True
    print("Setting image to " + filename)
    photo2 = tk.PhotoImage(file=filename)
    image.configure(image=photo2)
    image.image = photo2


win = tk.Tk()
win.geometry("750x450")

photo = tk.PhotoImage(file='car-jump.gif')
image = tk.Label(win, image=photo)
image.pack()

button = tk.Button(win, text="Click to change image", command=change_image)
button.pack()

show_car = False
win.mainloop()

When executed the code will show the car image.

When the button is clicked the image will change to a flower.

Stepper Motor Control Service

Today I have been busy developing a stepper motor service class. The service class will allow the Team Seaford robot to play crazy golf.




import RPi.GPIO as GPIO
import time

class ServiceStepMotor:

  PinPhase1 = 14
  PinPhase2 = 15
  PinPhase3 = 17
  PinPhase4 = 16
  
  Steps = [
  [1,0,0,0],
  [1,1,0,0],
  [0,1,0,0],
  [0,1,1,0],
  [0,0,1,0],
  [0,0,1,1],
  [0,0,0,1],
  [1,0,0,1]
  ]

  StepIndex = 0
  
  MotorOnTime = 0.05  
  
  ## Constructor
  # @param self Class pointer
  def __init__(self):
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    
    self.SetPinToOutput(self.PinPhase1)
    self.SetPinToOutput(self.PinPhase2)
    self.SetPinToOutput(self.PinPhase3)
    self.SetPinToOutput(self.PinPhase4)
    pass

  ## Change pin type to output
  # @param self Class pointer
  # @param pin Pin Number  
  def SetPinToOutput(self, pin):
    GPIO.setup(pin,GPIO.OUT)
    self.Off(pin)
    pass
  
  ## Turn output pin On
  # @param self Class pointer
  # @param pin Pin Number  
  def On(self, pin):
    print "On="+str(pin)
    GPIO.output(pin,1)
    pass

  ## Turn output pin off
  # @param self Class pointer
  # @param pin Pin Number
  def Off(self, pin):
    GPIO.output(pin, 0)
    pass
  
  ## Change the output state of a pin
  # @param self Class pointer
  # @param PinNumber GPIO pin number
  # @param PinValue The new value for the GPIO pin  
  def ChangeOuput(self, PinNumber, PinValue):
    GPIO.output(PinNumber, PinValue)  
    pass
  
  ## Move stepper motor
  # @param self Class Pointer
  # @param Direction 1 = Forwards, 0 = Backwards
  def Step(self, direction):
    
    # Increment / decrement step count based on direction
    if (direction):
      # forward
      self.StepIndex += 1
    else:
      # backwards
      self.StepIndex -= 1
    
    # Check if we have passed the end of the steps list  
    if (self.StepIndex >= len(self.Steps)):
      self.StepIndex = 0
    
    # Check if we have reached the start of the steps list
    if (self.StepIndex < 0):
      self.StepIndex = len(self.Steps) - 1
      
    # Set output pin states
    print "StepIndex=" + str(self.StepIndex)
    phase = self.Steps[self.StepIndex]
    self.ChangeOuput(self.PinPhase1, phase[0])
    self.ChangeOuput(self.PinPhase2, phase[1])
    self.ChangeOuput(self.PinPhase3, phase[2])
    self.ChangeOuput(self.PinPhase4, phase[3])
    #for i in range(len(phase)):
    #  self.On(phase[i])
    
    # Delay while motor turns
    time.sleep(self.MotorOnTime)
    pass

The example code below shows how to use the stepper motor service class.

import ServiceStepMotor
sm = ServiceStepMotor.ServiceStepMotor()

print"Start"

print "Step forwards 10 steps"
for i in range(10):
  print "Step forward " + str(i)
  sm.Step(True)
  
print "Step backwards 10 steps"
for i in range(10):
  print "Step backward " + str(i)
  sm.Step(False)
  
print "Finish" 

Moving Forwards


Our robot is alive and moving. At the heart of the Team Seaford robot control is the ServiceIo class. The ServiceIo class is responsible for controlling the four drive motors. Each motor is connected to a H bridge motor controller. The H bridge controllers require two inputs per motor. The inputs control the direction of travel.

import RPi.GPIO as GPIO
import time

class ServiceIo:
  MotorOnTime = 0.01
  
  # GPIO Pin Numbers
  PinDriveFrontLeftForward = 5    # flf
  PinDriveFrontLeftBackward = 13  # flb
  PinDriveFrontRightForward = 11  # frf
  PinDriveFrontRightBackward = 12 # frb
  PinDriveBackLeftForward = 9     # blf
  PinDriveBackLeftBackward = 10   # blb
  PinDriveBackRightForward = 7    # brf
  PinDriveBackRightBackward = 8   # brb

  ## Constructor
  # @param self Class pointer
  def __init__(self):
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    
    self.SetPinToOutput(self.PinDriveFrontLeftForward)
    self.SetPinToOutput(self.PinDriveFrontLeftBackward)
    self.SetPinToOutput(self.PinDriveFrontRightForward)
    self.SetPinToOutput(self.PinDriveFrontRightBackward)
    self.SetPinToOutput(self.PinDriveBackLeftForward)
    self.SetPinToOutput(self.PinDriveBackLeftBackward)
    self.SetPinToOutput(self.PinDriveBackRightForward)
    self.SetPinToOutput(self.PinDriveBackRightBackward)
    pass
  
  ## Change pin type to output
  # @param self Class pointer
  # @param pin Pin Number  
  def SetPinToOutput(self, pin):
    GPIO.setup(pin,GPIO.OUT)
    self.Off(pin)
    pass
  
  ## Turn output pin On
  # @param self Class pointer
  # @param pin Pin Number  
  def On(self, pin):
    print "On="+str(pin)
    GPIO.output(pin,1)
    pass

  ## Turn output pin off
  # @param self Class pointer
  # @param pin Pin Number
  def Off(self, pin):
    GPIO.output(pin, 0)
    pass
  
  ## Stop all drive motors
  # @param self Class pointer
  def DriveStop(self):
    self.Off(self.PinDriveFrontLeftForward) 
    self.Off(self.PinDriveFrontLeftBackward)
    self.Off(self.PinDriveFrontRightForward)
    self.Off(self.PinDriveFrontRightBackward)
    self.Off(self.PinDriveBackLeftForward)
    self.Off(self.PinDriveBackLeftBackward)
    self.Off(self.PinDriveBackRightForward)
    self.Off(self.PinDriveBackRightBackward) 
    pass
  
  ## Drive Forward
  # @param self Class pointer
  def DriveForward(self):
    self.On(self.PinDriveFrontLeftForward)
    self.On(self.PinDriveFrontRightForward)
    self.On(self.PinDriveBackLeftForward)
    self.On(self.PinDriveBackRightForward)
    self.Off(self.PinDriveFrontLeftBackward)
    self.Off(self.PinDriveFrontRightBackward)
    self.Off(self.PinDriveBackLeftBackward)
    self.Off(self.PinDriveBackRightBackward)
    time.sleep(self.MotorOnTime)
    pass

  ## Drive Backward
  # @param self Class pointer
  def DriveBackward(self):
    self.On(self.PinDriveFrontLeftBackward)
    self.On(self.PinDriveFrontRightBackward)
    self.On(self.PinDriveBackLeftBackward)
    self.On(self.PinDriveBackRightBackward)
    self.Off(self.PinDriveFrontLeftForward)
    self.Off(self.PinDriveFrontRightForward)
    self.Off(self.PinDriveBackLeftForward)
    self.Off(self.PinDriveBackRightForward)
    time.sleep(self.MotorOnTime)
    pass
    
  ## Drive Left
  # @param self Class pointer
  def DriveLeft(self):
    self.On(self.PinDriveFrontLeftForward)
    self.Off(self.PinDriveFrontLeftBackward)
    self.On(self.PinDriveBackLeftForward)
    self.Off(self.PinDriveBackLeftBackward)
    self.On(self.PinDriveFrontRightBackward)
    self.Off(self.PinDriveFrontRightForward)
    self.On(self.PinDriveBackRightBackward)
    self.Off(self.PinDriveBackRightForward)
    time.sleep(self.MotorOnTime)
    pass
      
  ## Drive Right
  # @param self Class pointer
  def DriveRight(self):
    self.On(self.PinDriveFrontRightForward)
    self.Off(self.PinDriveFrontRightBackward)
    self.On(self.PinDriveBackRightForward)
    self.Off(self.PinDriveBackRightBackward)
    self.On(self.PinDriveFrontLeftBackward)
    self.Off(self.PinDriveFrontLeftForward)
    self.On(self.PinDriveBackLeftBackward)
    self.Off(self.PinDriveBackLeftForward)
    time.sleep(self.MotorOnTime)
    pass

The following code show how to use the ServiceIo within a simple program, which responds to user input from the keyboard.

import ServiceIo
import time

io = ServiceIo.ServiceIo()
io.DriveStop()


while True:
  mode = raw_input('Direction (f,b,l,r:')
  if (mode == 'f'):
    io.DriveForward()

  if(mode == 'b'):
    io.DriveBackward()

  if(mode=='l'):
    io.DriveLeft()

  if(mode=='r'):
    io.DriveRight()

  time.sleep(2)
  print("off")
  io.DriveStop()

Generate safe filenames using Python

This function removes illegal  characters to create file names that are safe to use on most operating systems.

import string

## Make a file name that only contains safe charaters
# @param inputFilename A filename containing illegal characters
# @return A filename containing only safe characters
def makeSafeFilename(inputFilename):   
  try:
     safechars = string.letters + string.digits + " -_."
    return filter(lambda c: c in safechars, inputFilename)
   except:
     return ""  
  pass

print makeSafeFilename("test1******.txt")  # test1.txt

print makeSafeFilename("test2:\.txt") # test2.txt

print makeSafeFilename("test39328764876!%^&*().txt") # test39328764876.txt