Python GUI'den kurtulma


#1

Arkadaşlar hayırlı akşamlar. Elimde github’dan almış olduğum aşağıdaki kodlar var. Bir rc car projesinde kullanıyorum ve gayet sorunsuz çalışıyor aslında. Ancak yazan arkadaş burada tkinter kullanmış ve ismi sanırım “after loop” diye geçen self.root.after(10, self._check_key_press) satırını kullanmış. Ben GUI’den kurtulmak istiyorum, biraz inceledim kodları bir kaç değişiklikte denedim ama istediğim sonucu elde edemedim. Konuyla ilgili yardımcı olabilecek arkadaşlara şimdiden teşekkürler.

import tkinter as tk
import serial

class Controller:
def __init__(self):
    self.pressed = {}
    self.prevPressed = {}
    self._initPresses()
    self._create_ui()
    self.ser = serial.Serial(
        port='/dev/ttyACM0',
        baudrate=115200,
        parity=serial.PARITY_ODD,
        stopbits=serial.STOPBITS_TWO,
        bytesize=serial.SEVENBITS
    )
    self.ser.isOpen()

def _initPresses(self):
    self.pressed["w"] = False
    self.pressed["a"] = False
    self.pressed["s"] = False
    self.pressed["d"] = False
    self.prevPressed["w"] = False
    self.prevPressed["a"] = False
    self.prevPressed["s"] = False
    self.prevPressed["d"] = False

def start(self):
    self._check_key_press()
    self.root.mainloop()

def _check_for_press(self, key, command):
    if self._is_pressed(key):
        self.prevPressed[key] = True
        self.ser.write(command)
        print(key + " pressed")

def _check_for_release(self, key, command):
    if self._is_released(key):
        self.prevPressed[key] = False
        self.ser.write(command)
        print(key + " released")

def _check_key_press(self):
    self._check_for_press("w", b"\x01")
    self._check_for_release("w", b"\x02")
    self._check_for_press("s", b"\x03")
    self._check_for_release("s", b"\x04")
    self._check_for_press("d", b"\x05")
    self._check_for_release("d", b"\x06")
    self._check_for_press("a", b"\x07")
    self._check_for_release("a", b"\x08")

    self.root.after(10, self._check_key_press)

def _is_pressed(self, key):
    return self.pressed[key] and self.prevPressed[key] == False

def _is_released(self, key):
    return self.pressed[key] == False and self.prevPressed[key]

def _create_ui(self):
    self.root = tk.Tk()
    self.root.geometry('400x300')
    self._set_bindings()

def _set_bindings(self):
    for char in ["w","s","d", "a"]:
        self.root.bind("<KeyPress-%s>" % char, self._pressed)
        self.root.bind("<KeyRelease-%s>" % char, self._released)
        self.pressed[char] = False

def _pressed(self, event):
    self.pressed[event.char] = True

def _released(self, event):
    self.pressed[event.char] = False

if __name__ == "__main__":
p = Controller()
p.start()

#2

Yani GUI’den kurtulup bu işlemleri komut satırında mı yapmak istiyorsunuz?


#3

Evet hocam GUI’ye ihtiyacım yok bu projede.


#4

Peki GUI olmadığında kontrolleri nasıl yapmayı düşünüyorsunuz? Aklıma gelen bir yöntem, kullanıcıdan konsol ekranında girdi alarak yönlendirme yapmak. Sizin bir fikriniz var mı?


#5

O şekilde ENTER tuşuna basmadan girdiyi alabiliyor muyum? Eğer öyleyse işimi görebilir çünkü yaptığım şey ile klavyeden w, a, s, d tuşlarını kullanarak seri port üzerinden arduino kullanarak oyuncak arabayı kontrol ediyorum.


#6

Eğer bahsettiğim şekilde kullanıcıdan girdi alırsanız, o zaman Enter’a basmak zorundasınız. Ancak Enter’a basmadan sadece tuşa basar basmaz tepki vermesini isterseniz, işletim sisteminize göre çözümlere bakabiliriz. Ayrıca, iki tuşa aynı anda bastığınızda ne olacağı konusunu da düşünmek lazım.


#7

İşte bu kodlar ile bilgisayar oyunu oynar gibi 2 tuşa da bastığımda işlem yapabiliyorum. Tek istediğim bir pencere açılıyor ve işlemler onun üzerinden yapılıyor ondan kurtulmak. İşletim sistemi raspberry pi’nin rasbian işletim sistemi.


#8

Curses modülüne bakmak isteyebilirsiniz.


#9

Eğer konsol kullanarak yönetmeye kalkarsanız, GUI üzerinde yaptığınız iki tuşa aynı anda basarak yönlendirme işlemini yapamazsınız. Tek seferde sadece bir yöne kullanım imkanı verir. Konsol uygulamaları bu tür işlemler için sıkıntılı olur.


#10

Siz hangi modülü kullanarak denediniz hocam? Şuan İsmail hocanın önerdiği curses modülünü inceliyorum onunla yapılmış gibi ama daha test edemedim henüz.


#11

Modülü daha önceden kullandım. Evet yapılabiliyor ancak benim bahsettiğim konu farklı. Yani Mesela arabayı sağ-yukarı yönünde hareket ettirmek istediğinizde, “w” ve “d” tuşlarına aynı anda basamazsınız. Konsoldan bunu algılamak zor.

Sadece tek bir yöne basma işlemi kolay. Ben tek seferde bir tuşa basarak hareket ettirmek istiyorum diyorsanız, o zaman yapılabilir.


#12

Yok ben sizin bahsettiğiniz gibi çift tuş kombinasyonunda da çalışabilmesini istiyorum. O halde bu modül yerine başka modül araştırmam gerekecek.


#13

Pynput modülü işinizi halledebilir.

şöyle örnek bir kod belki yararlı olabilir. gelen değer ile if kontrolleri ile halledilebilir bence :confused:

from pynput import keyboard
COMBINATIONS = [{keyboard.Key}]
current = set()
def on_press(key):    
    print(key)
def on_release(key):
    print(key)
with keyboard.Listener(on_press=on_press,on_release=on_release) as listener:
    listener.join()