tkinter, frame do przycisków

0

Cześć!
Jestem nowy w tkinterze i mam problem. Otóż wygląda to następująco, chciałbym dodać ramkę do wszystkich przycisków, poniżej kod bez podejmowania żadnych prób modyfikacji.
screenshot-20211112152429.png

Bawiłem się trochę z tym, lecz pojawia się błąd którego nie rozumiem (wiem, w 39 linijce pojawia się tylko kolumna 4, lecz chciałem wpisać cokolwiek żeby zobaczyć czy to zadziała).
Jak kogoś będą bolały oczy po przeczytaniu tego co napisałem w pythonie to z góry przepraszam, ale jeszcze raz powtórzę, że dopiero się uczę

screenshot-20211112152310.png

screenshot-20211112152112.png

Po dodaniu w 58 linijce tego frame1 pojawia się następny błąd którego również nie rozumiem, ponieważ nie ma tam żadnego "bd"

screenshot-20211112153359.png

screenshot-20211112153409.png

Dziękuję za pomoc!!

0

Społeczność forum wymaga od Ciebie zapoznania się z tym tematem:

Dlaczego nie należy zamieszczać kodu w postaci obrazków


XarrrdaS napisał(a):

chciałbym dodać ramkę do wszystkich przycisków

Proszę, oto Twoja ramka :]
screenshot-20211112211626.png

0

@Spine:


symbole = ['7', '8', '9', '/', '\u21BA', 'C', '4', '5', '6', '*', '(', ')',  '1',  '2', '3', '-', 'x^2', '\u221A', '0',
           ',', '%', '+']

COLOR = '#36393E'

def inicjalizacjaPrzycisków(root, ekran, info):

    #frame1 = tkinter.Frame(root,pady=1, padx=1)
    #frame1.grid(column=4)


    przyciski = [tkinter.Button(root, text=symbol, bg=COLOR, borderwidth=0, activebackground='#9FA2A2')
                 for symbol in symbole]

    #for i in range(len(przyciski)):
    #    przyciski[i].grid(row=i, column=i)

    j = len(ekran) + 2
    for i in range(len(przyciski)):
        if i % 6 == 0:
            j += 1
        margines = 20 if len(symbole[i]) == 1 else 10
        przyciski[i].grid(row=j, column=i % 6, ipady=15, ipadx=margines)
        przyciski[i].configure(command=przyciskKlik(pole_na_dane, przyciski[i]['text']))
    znak_rownosc = tkinter.Button(root, text='=', bg='#B5A519', borderwidth=0, command=oblicz(pole_na_dane, ekran, info))
    znak_rownosc.grid(row=len(ekran) + 6, column=4, columnspan=2, ipady=5, ipadx=56)
    return przyciski
0

@XarrrdaS:
Oto cały kod, problem jest w 4 funkcji od góry

import tkinter



symbole = ['7', '8', '9', '/', '\u21BA', 'C', '4', '5', '6', '*', '(', ')',  '1',  '2', '3', '-', 'x^2', '\u221A', '0',
           ',', '%', '+']


COLOR = '#36393E'


def inicjalizacjaOkienka():
    root = tkinter.Tk()
    root.geometry('463x453')
    root.title('Kalkulator')
    root.configure(bg=COLOR)
    return root


def inicjalizacjaEkranu(root):
    ekran = [tkinter.Label(root, bg='#C0CBCB',width=65, anchor='w', borderwidth=2) for i in range(3)]
    for i in range(len(ekran)):
        ekran[i].grid(row=i, columnspan=6, ipady=15, ipadx=1)
    return ekran


def inicjalizacjaPolaNaDane(root, ekran):
    pole_na_dane = tkinter.Entry(root, borderwidth=0, highlightcolor='white', highlightbackground='white')
    pole_na_dane.grid(row=len(ekran), columnspan=6, ipadx=171, ipady=10)
    info = tkinter.Label(root, bg='white', width=65, anchor='w', borderwidth=2)
    info.grid(row=len(ekran) + 1, columnspan=6, ipady=15, ipadx=1)
    return pole_na_dane, info


def inicjalizacjaPrzycisków(root, ekran, info):

    #frame1 = tkinter.Frame(root,pady=1, padx=1)
    #frame1.grid(column=4)


    przyciski = [tkinter.Button(root, text=symbol, bg=COLOR, borderwidth=0, activebackground='#9FA2A2')
                 for symbol in symbole]

    #for i in range(len(przyciski)):
    #    przyciski[i].grid(row=i, column=i)

    j = len(ekran) + 2
    for i in range(len(przyciski)):
        if i % 6 == 0:
            j += 1
        margines = 20 if len(symbole[i]) == 1 else 10
        przyciski[i].grid(row=j, column=i % 6, ipady=15, ipadx=margines)
        przyciski[i].configure(command=przyciskKlik(pole_na_dane, przyciski[i]['text']))
    znak_rownosc = tkinter.Button(root, text='=', bg='#B5A519', borderwidth=0, command=oblicz(pole_na_dane, ekran, info))
    znak_rownosc.grid(row=len(ekran) + 6, column=4, columnspan=2, ipady=5, ipadx=56)
    return przyciski


def przyciskKlik(pole_na_dane, symbol):
    def f():
        if symbol == '\u21BA':
            tekst = pole_na_dane.get()[:-1]
            pole_na_dane.delete(0, tkinter.END)
            pole_na_dane.insert(tkinter.END, tekst)
        elif symbol == 'C':
            pole_na_dane.delete(0, tkinter.END)
        else:
            text = symbol if symbol != 'x^2' else '^2'
            pole_na_dane.insert(tkinter.END, text)
    return f


def oblicz(pole_na_dane, ekran, info):
    def czyPoprawnyOstatniZnak(tekst):
        i = 1
        while tekst[-i] == ')':
            i += 1
        return tekst[-i].isdigit()

    def czyWielokrotneOperatory(tekst):
        for i in range(len(tekst)):
            if not tekst[i].isdigit() and not tekst[i + 1].isdigit():
                return True
        return False

    def zamienZnakPotegi(tekst):
        for i in range(len(tekst)):
            if tekst[i] == '^':
                tekst = tekst[:i] + '**' + tekst[i + 1:]
        return tekst

 #   def zamienZnakPierwiastka(tekst):
    #    for i in range(len(tekst)):
   #         if tekst[i] == '\u221A':
     #           tekst = tekst[:i] + str(math.sqrt(i)) + tekst[i + 1:]
     #   return tekst

    def f():
        tekst = pole_na_dane.get()

        if not czyPoprawnyOstatniZnak(tekst) or czyWielokrotneOperatory(tekst):
            info['text'] = 'Błędne wyrażenie!'
        else:
            for i in range(1, len(ekran)):
                if ekran[i]['text']:
                    ekran[i - 1]['text'] = ekran[i]['text']
            if '^' in tekst:
                wyrazenie = zamienZnakPotegi(tekst)
                ekran[-1]['text'] = tekst + ' = ' + str(eval(wyrazenie))
          #  if '\u221A' in tekst:
            #    wyrazenie2 = zamienZnakPierwiastka(tekst)
         #       ekran[1]['text'] = tekst + ' = ' + str(eval(wyrazenie2))
            else:
                ekran[-1]['text'] = tekst + ' = ' + str(eval(tekst))
    return f


def podswietlenie(przyciski):
    def on_enter(przyciski):
        przyciski['background'] = 'green'

    def on_leave(przyciski):
        przyciski['background'] = '#B5A519'

    for c in range(1, 5):
        przyciski[c].bind("<Enter>", on_enter)
        przyciski[c].bind("<Leave>", on_leave)



if __name__ == '__main__':
    root = inicjalizacjaOkienka()

    ekran = inicjalizacjaEkranu(root)

    pole_na_dane, info = inicjalizacjaPolaNaDane(root, ekran)

    przyciski = inicjalizacjaPrzycisków(root, ekran, info)

#    podswietlenie = podswietlenie(przyciski)

    root.mainloop()
0

Chodzi o odstęp pionowy pomiędzy rzędami?
screenshot-20211113170035.png
Jeśli tak to trzeba użyć obu: ipady i pady.
Jeszcze trzeba powalczyć z rozmiarem okna. Może stały? I innymi przyciskami (rozmiar i pozycja)

Pozdrawiam
Radek Głębicki

0

@Radosław Głębicki: Mógłbyś proszę pokazać zmiany w kodzie? jeżeli chodzi o rozmiar okna to będę to zmieniał

0

przyciski[i].grid(row=j, column=i % 6, pady=5, padx=5, ipady=15, sticky="ew")
i
znak_rownosc.grid(row=len(ekran) + 6, column=4, columnspan=2, pady=5, padx=5, ipady=15, sticky="ew")

margines raczej już nie potrzebujesz. Problemem jest jeszcze przycisk x^2. Ma trzy znaki. Najprościej dodaj wszędzie dodatkowe spacje (" 1 ") i zastosuj czcionkę Mono.

Pozdrawiam
Radek Głębicki

0

@Radosław Głębicki: Chodziło mi o takie coś, że jest ramka na około przycisku, lecz nie z funkcji "borderwidth= ", takie coś jak poniżej. Próbuję to dodać do mojego kodu lecz dostaję błąd: _tkinter.TclError: unknown option "-class". Nie wiem co on oznacza, ani co poprawić żeby zniknął.

from tkinter import *

App = Tk()

Border = LabelFrame(App, bd=1, bg="black", relief=FLAT)
Border.pack(padx=10, pady=10)

Btn1 = Button(Border, text="Button", font="Arial 16 bold", width=16, activebackground='#9FA2A2', fg="#36393E", borderwidth=0, relief=FLAT)
Btn1.pack()

App.mainloop()
0

@XarrrdaS: Tak samo walczę z podświetleniem przycisków podczas najechania na nie, oto co wykombinowałem(ostatnia funkcja).Generalnie to działa, lecz podczas najechania na jaki kolwiek przycisk od razu konsola zwraca błąd: TypeError: 'Event' object does not support item assignment i również nie rozumiem co on oznacza. Z góry dziękuję za pomoc.

import tkinter
from tkinter import *


symbole = ['7', '8', '9', '/', '\u21BA', 'C', '4', '5', '6', '*', '(', ')',  '1',  '2', '3', '-', 'x^2', '\u221A', '0',
           ',', '%', '+']


COLOR = '#36393E'

def inicjalizacjaOkienka():
    root = tkinter.Tk()
    root.geometry('466x500')
    root.resizable(0, 0)
    root.title('Kalkulator')
    root.configure(bg=COLOR)
    return root


def inicjalizacjaEkranu(root):
    ekran = [tkinter.Label(root, bg='#C0CBCB',width=65, anchor='w', borderwidth=2) for i in range(3)]
    for i in range(len(ekran)):
        ekran[i].grid(row=i, columnspan=6, ipady=15, ipadx=1)
    return ekran


def inicjalizacjaPolaNaDane(root, ekran):
    pole_na_dane = tkinter.Entry(root, borderwidth=0, highlightcolor='white', highlightbackground='white')
    pole_na_dane.grid(row=len(ekran), columnspan=6, ipadx=171, ipady=10)
    info = tkinter.Label(root, bg='white', width=65, anchor='w', borderwidth=2)
    info.grid(row=len(ekran) + 1, columnspan=6, ipady=15, ipadx=1)
    return pole_na_dane, info


def inicjalizacjaPrzycisków(root, ekran, info):

  #  buttonborder = tkinter.Frame(highlightbackground="black",
   #                         highlightthickness=.5, bd=0)
 #   Border = LabelFrame(root, bd=1, bg="black", relief=FLAT)
  #  Border.grid(padx=10, pady=10)

    przyciski = [tkinter.Button(root,text=symbol, bg=COLOR, borderwidth=1,  activebackground='#9FA2A2')
                 for symbol in symbole]


    j = len(ekran) + 2
    for i in range(len(przyciski)):
        if i % 6 == 0:
            j += 1
       # margines = 20 if len(symbole[i]) == 1 else 10
        przyciski[i].grid(row=j, column=i % 6, pady=5, padx=5, ipady=15, sticky="ew")
        przyciski[i].configure(command=przyciskKlik(pole_na_dane, przyciski[i]['text']))
    znak_rownosc = tkinter.Button(root, text='=', bg='#B5A519', borderwidth=0, command=oblicz(pole_na_dane, ekran, info))
    znak_rownosc.grid(row=len(ekran) + 6, column=4, columnspan=2, pady=5, padx=5, ipady=15, sticky="ew")
    return przyciski


def przyciskKlik(pole_na_dane, symbol):
    def f():
        if symbol == '\u21BA':
            tekst = pole_na_dane.get()[:-1]
            pole_na_dane.delete(0, tkinter.END)
            pole_na_dane.insert(tkinter.END, tekst)
        elif symbol == 'C':
            pole_na_dane.delete(0, tkinter.END)
        else:
            text = symbol if symbol != 'x^2' else '^2'
            pole_na_dane.insert(tkinter.END, text)
    return f


def oblicz(pole_na_dane, ekran, info):
    def czyPoprawnyOstatniZnak(tekst):
        i = 1
        while tekst[-i] == ')':
            i += 1
        return tekst[-i].isdigit()

    def czyWielokrotneOperatory(tekst):
        for i in range(len(tekst)):
            if not tekst[i].isdigit() and not tekst[i + 1].isdigit():
                return True
        return False

    def zamienZnakPotegi(tekst):
        for i in range(len(tekst)):
            if tekst[i] == '^':
                tekst = tekst[:i] + '**' + tekst[i + 1:]
        return tekst

 #   def zamienZnakPierwiastka(tekst):
    #    for i in range(len(tekst)):
   #         if tekst[i] == '\u221A':
     #           tekst = tekst[:i] + str(math.sqrt(i)) + tekst[i + 1:]
     #   return tekst

    def f():
        tekst = pole_na_dane.get()

        if not czyPoprawnyOstatniZnak(tekst) or czyWielokrotneOperatory(tekst):
            info['text'] = 'Błędne wyrażenie!'
        else:
            for i in range(1, len(ekran)):
                if ekran[i]['text']:
                    ekran[i - 1]['text'] = ekran[i]['text']
            if '^' in tekst:
                wyrazenie = zamienZnakPotegi(tekst)
                ekran[-1]['text'] = tekst + ' = ' + str(eval(wyrazenie))
          #  if '\u221A' in tekst:
            #    wyrazenie2 = zamienZnakPierwiastka(tekst)
         #       ekran[1]['text'] = tekst + ' = ' + str(eval(wyrazenie2))
            else:
                ekran[-1]['text'] = tekst + ' = ' + str(eval(tekst))
    return f


def podswietlenie(przyciski):
    def on_enter(przyciski):
        przyciski['background'] = 'green'

    def on_leave(przyciski):
        przyciski['background'] = '#B5A519'


    for i in przyciski:
        i.bind("<Enter>", on_enter)
        i.bind("<Leave>", on_leave)



if __name__ == '__main__':
    root = inicjalizacjaOkienka()

    ekran = inicjalizacjaEkranu(root)

    pole_na_dane, info = inicjalizacjaPolaNaDane(root, ekran)

    przyciski = inicjalizacjaPrzycisków(root, ekran, info)

    podswietlenie = podswietlenie(przyciski)

    root.mainloop()
0

@XarrrdaS: tak, activebackground zmienia kolor podczas kliknięcia, a mi chodzi właśnie o to, żeby button zmieniał kolor podczas najechania kursorem na niego, tak samo ta ramka przycisku, chciałbym żeby to wyglądało jak z kodu poniżej, lecz gdy stosuje to do mojego programu to zwraca mi dziwny (dla mnie) kod błędu: _tkinter.TclError: unknown option "-class", jak już wspomniałem wcześniej nie wiem do końca co on oznacza i nie wiem co zmienić aby ten błąd zniknął.

from tkinter import *

App = Tk()

Border = LabelFrame(App, bd=1, bg="black", relief=FLAT)
Border.pack(padx=10, pady=10)

Btn1 = Button(Border, text="Button", font="Arial 16 bold", width=16, activebackground='#9FA2A2', fg="#36393E", borderwidth=0, relief=FLAT)
Btn1.pack()

App.mainloop()
0
def podswietlenie(przyciski):
    def on_enter(event):
        event.widget['background'] = 'green'

    def on_leave(event):
        event.widget['background'] = '#B5A519'

    for i in przyciski:
        i.bind("<Enter>", on_enter )
        i.bind("<Leave>", on_leave )
0
App = Tk()

Btn1 = Button(App, text="Button", font="Arial 16 bold", width=16, activebackground='#888',
			  fg="#36393E", bd=0, relief=FLAT,
			  highlightbackground="#22f",highlightthickness=2)
Btn1.pack()

App.mainloop()

A tak button też ma ramkę i się podświetla po najechaniu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1