首页 > 解决方案 > 用于 ATM 和 Arduino 矩阵键盘的 Tkinter GUI

问题描述

我正在尝试为 ATM 机项目制作 GUI。我想在连接到 Arduino 的 4x4 矩阵键盘上按下按钮时切换框架。我写了一些代码来读取 Arduino 的串行输出。Arduino代码:

#include <Keypad.h>

const byte ROWS = 4; 
const byte COLS = 4; 

char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte rowPins[ROWS] = {9, 8, 7, 6}; 
byte colPins[COLS] = {5, 4, 3, 2}; 

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

void setup(){
  Serial.begin(9600);
}
  
void loop(){
  char customKey = customKeypad.getKey();
  
  if (customKey){
    Serial.print(customKey);
  }
}

我使用了 Thread x 以便它可以运行 while True 循环,但是当我运行我的 GUI 并想要加载 PageTwo 时,框架卡在 PageOne 上,直到我按下键盘上的某些东西。我认为问题在于 PageTwo 在 Thread 完成后加载。Python代码:

import tkinter as tk
import time
import serial
import threading


class SampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.title('ABN-MANBRO')
        self._frame = None
        self.switch_frame(StartPage)
        self.geometry('1920x1080')

    def switch_frame(self, frame_class):
        """Destroys current frame and replaces it with a new one."""
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.pack(fill="both", expand=1)

    def checkKeypad(self):
        ser = serial.Serial("COM3", 9600, timeout=1)
        while True:
            keypad = ser.read()
            keypad = keypad.decode()
            if keypad:
                print(keypad)
                return


# start page
class StartPage(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)

        self.bg_image = tk.PhotoImage(file='images/beginscherm.png')
        self.bg_label = tk.Label(self, image=self.bg_image)
        self.bg_label.place(x=0, y=0)

        button1 = tk.Button(self, text="Go to Page One",
                            command=lambda: master.switch_frame(PageOne))
        button1.pack()

# pincode-check
class PageOne(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)

        self.bg_image = tk.PhotoImage(file='images/pincode-check-scherm.png')
        self.bg_label = tk.Label(self, image=self.bg_image)
        self.bg_label.place(x=0, y=0)

        tk.Button(self, text="Page 2",
                  command=lambda: master.switch_frame(PageTwo)).pack()


# option page
class PageTwo(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)

        self.bg_image = tk.PhotoImage(file='images/Keuzemenu-scherm.png')
        self.bg_label = tk.Label(self, image=self.bg_image)
        self.bg_label.place(x=0, y=0)

        button = tk.Button(self, text="Go to the start page", command=lambda: master.switch_frame(StartPage))

        self.wd = tk.PhotoImage(file='images/withdrawknop.png')
        withdrawButton = tk.Button(self, image=self.wd, borderwidth=0,
                                   command=lambda: master.switch_frame(PageThree))

        self.bal = tk.PhotoImage(file='images/balanceknop.png')
        balButton = tk.Button(self, image=self.bal, command=lambda: master.switch_frame(PageFour), borderwidth=0)

        self.fast = tk.PhotoImage(file='images/fast70knop.png')
        fastButton = tk.Button(self, image=self.fast, command=None, borderwidth=0)

        self.abort = tk.PhotoImage(file='images/abort knop.png')
        abortButton = tk.Button(self, image=self.abort, command=lambda: master.switch_frame(PageEight), borderwidth=0)

        button.pack()
        withdrawButton.place(x=1400, y=500)
        balButton.place(x=1400, y=640)
        fastButton.place(x=1400, y=780)
        abortButton.place(x=80, y=780)

        self.x = threading.Thread(target=master.checkKeypad())
        self.x.start()

标签: pythontkinterarduinokeypad

解决方案


推荐阅读