Pack python: Метод pack. Урок 3 курса «Tkinter. Программирование GUI на Python»

Содержание

Метод pack. Урок 3 курса «Tkinter. Программирование GUI на Python»

Прежде чем продолжить знакомство с виджетами GUI остановимся на вопросе их расположения в окне. Это важный вопрос, так как от продуманности интерфейса во многом зависит удобство использования программы. Организуя виджеты в пространстве, программист отчасти становится дизайнером, разработчиком интерфейсов.

В Tkinter существует три так называемых менеджера геометрии – упаковщик, сетка и размещение по координатам. В этом уроке будет рассмотрен первый как наиболее простой и часто используемый, остальные два упомянем позже.

Упаковщик (packer) вызывается методом pack, который имеется у всех виджетов-объектов. Мы уже использовали его. Если к элементу интерфейса не применить какой-либо из менеджеров геометрии, то он не отобразится в окне. При этом в одном окне (или любом другом родительском виджете) нельзя комбинировать разные менеджеры. Если вы начали размещать виджеты методом pack, не пытайтесь тут же использовать методы grid (сетка) и place (место).

Если в упаковщики не передавать аргументы, то виджеты будут располагаться вертикально, друг над другом. Тот объект, который первым вызовет pack, будет вверху. Который вторым – под первым, и так далее.

У метода pack есть параметр side (сторона), который принимает одно из четырех значений-констант tkinterTOP, BOTTOM, LEFT, RIGHT (верх, низ, лево, право). По умолчанию, когда в pack не указывается side, его значение равняется TOP. Из-за этого виджеты располагаются вертикально.

Создадим четыре раскрашенные метки

...
l1 = Label(width=7, height=4,
           bg='yellow', text="1")
l2 = Label(width=7, height=4,
           bg='orange', text="2")
l3 = Label(width=7, height=4,
           bg='lightgreen', text="3")
l4 = Label(width=7, height=4,
           bg='lightblue', text="4")
...

и рассмотрим разные комбинации значений сайда:

Проблема двух последних вариантов в том, что если надо разместить виджеты квадратом, т. е. два сверху, два снизу ровно под двумя верхними, то сделать это проблематично, если вообще возможно. Поэтому прибегают к вспомогательному виджету – фрейму (рамке), который порождается от класса Frame.

Фреймы размещают на главном окне, а уже в фреймах – виджеты:

from tkinter import *
root = Tk()
f_top = Frame(root)
f_bot = Frame(root)
l1 = Label(f_top, width=7, height=4,
           bg='yellow', text="1")
l2 = Label(f_top, width=7, height=4,
           bg='orange', text="2")
l3 = Label(f_bot, width=7, height=4,
           bg='lightgreen', text="3")
l4 = Label(f_bot, width=7, height=4,
           bg='lightblue', text="4")
 
f_top.pack()
f_bot.pack()
l1.pack(side=LEFT)
l2.pack(side=LEFT)
l3.pack(side=LEFT)
l4.pack(side=LEFT)
 
root.mainloop()
 

Результат:

Кроме Frame существует похожий класс LabelFrame – фрейм с подписью. В отличие от простого фрейма у него есть свойство text.

… 
f_top = LabelFrame(text="Верх")
f_bot = LabelFrame(text="Низ")
… 

Кроме side у pack есть другие параметры-свойства. Можно задавать внутренние (ipadx и ipady) и внешние (padx и pady) отступы:

Когда устанавливаются внутренние отступы, то из-за того, что side прибивает виджет к левой границе, справа получаем отступ в 20 пикселей, а слева – ничего. Можно частично решить проблему, заменив внутренние отступы рамки на внешние отступы у меток.

Но тут появляется промежуток между самими метками. Чтобы его убрать, пришлось бы каждый виджет укладывать в свой собственный фрейм. Отсюда делаем вывод, что упаковщик Tkinter удобен только для относительно простых интерфейсов.

Следующие два свойства – fill (заполнение) и expand (расширение). По-умолчанию expand равен нулю (другое значение – единица), а fillNONE (другие значения BOTH, X, Y). Создадим окно с одной меткой:

from tkinter import *
 
root = Tk()
l1 = Label(text="This is a label",
           width=30, height=10,
           bg="lightgreen")
l1. pack()
root.mainloop()

Если начать расширять окно или сразу раскрыть его на весь экран, то метка окажется вверху по вертикали и в середине по горизонтали. Причина, по которой метка не в середине по вертикали заключается в том, что side по-умолчанию равен TOP, и метку прибивает к верху.

Если установить свойство expand в 1, то при расширении окна метка будет всегда в середине:

… 
l1.pack(expand=1) 
… 

Свойство fill заставляет виджет заполнять все доступное пространство. Заполнить его можно во всех направлениях или только по одной из осей:

… 
l1.pack(expand=1, fill=Y)
… 

Последняя опция метода packanchor (якорь) – может принимать значения N (north – север), S (south – юг), W (west – запад), E (east – восток) и их комбинации:

… 
l1.pack(expand=1, anchor=SE)
… 

Практическая работа

Перепишите программу из практической работы предыдущего урока так, чтобы интерфейс выглядел примерно следующим образом:

Курс с примерами решений практических работ:
android-приложение,
pdf-версия.

Разметки pack, grid и place для позиционирования в Tkinter

В данном уроке по изучению Tkinter мы познакомимся с менеджерами разметки. Когда мы создаем графический интерфейс нашего приложения, мы определяем, какие виджеты будем использовать, и как они будут расположены в приложении. Для того, чтобы организовать виджеты в приложении, используются специальные невидимые объекты – менеджеры разметки.

Содержание курса

  1. Создание окна по центру и кнопка выхода в Tkinter
  2. Разметка виджетов в Tkinter — pack, grid и place
  3. Виджеты Checkbutton, Label, Scale и Listbox в Tkinter
  4. Меню, подменю и панель инструментов в Tkinter
  5. Диалоговые окна в Tkinter
  6. Рисуем линии, прямоугольники, круг и текст в Tkinter
  7. Пишем игру змейка на Tkinter

Содержание статьи

Существует два вида виджетов:

  • контейнеры;
  • дочерние виджеты.

Контейнеры объединяют виджеты для формирования разметки. У Tkinter есть три встроенных менеджера разметки: pack, grid и place.

  • Place – это менеджер геометрии, который размещает виджеты, используя абсолютное позиционирование.
  • Pack – это менеджер геометрии, который размещает виджеты по горизонтали и вертикали.
  • Grid – это менеджер геометрии, который размещает виджеты в двухмерной сетке.

Метод place() в Tkinter — Абсолютное позиционирование

В большинстве случаев разработчикам необходимо использовать менеджеры разметки. Есть несколько ситуаций, в которых следует использовать именно абсолютное позиционирование. В рамках абсолютного позиционирования разработчик определяет позицию и размер каждого виджета в пикселях. Во время изменения размеров окна размер и позиция виджетов не меняются.

Изображения из примера:

Сохраните их в папке рядом с файлом absolute. py код для которого будет ниже.

Таким образом, на разных платформах приложения выглядят по-разному. То, что выглядит нормально на Linux, может отображаться некорректно на Mac OS. Изменение шрифтов в нашем приложении также может испортить разметку. Если мы переведем наше приложение на другой язык, мы должны доработать и разметку.

from PIL import Image, ImageTk
from tkinter import Tk, BOTH
from tkinter.ttk import Frame, Label, Style

class Example(Frame):

def __init__(self):
super().__init__()

self.initUI()

def initUI(self):

self.master.title(«Absolute positioning»)
self.pack(fill=BOTH, expand=1)

Style().configure(«TFrame», background=»#333″)

bard = Image.open(«bardejov.jpg»)
bardejov = ImageTk.PhotoImage(bard)
label1 = Label(self, image=bardejov)
label1.image = bardejov
label1.place(x=20, y=20)

rot = Image.open(«rotunda.jpg»)
rotunda = ImageTk. PhotoImage(rot)
label2 = Label(self, image=rotunda)
label2.image = rotunda
label2.place(x=40, y=160)

minc = Image.open(«mincol.jpg»)
mincol = ImageTk.PhotoImage(minc)
label3 = Label(self, image=mincol)
label3.image = mincol
label3.place(x=170, y=50)

def main():

root = Tk()
root.geometry(«300×280+300+300»)
app = Example()
root.mainloop()

if __name__ == ‘__main__’:
main()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

from PIL import Image, ImageTk

from tkinter import Tk, BOTH

from tkinter. ttk import Frame, Label, Style

 

class Example(Frame):

 

    def __init__(self):

        super().__init__()

 

        self.initUI()

 

 

    def initUI(self):

 

        self.master.title(«Absolute positioning»)

        self.pack(fill=BOTH, expand=1)

 

        Style().configure(«TFrame», background=»#333″)

 

        bard = Image.open(«bardejov.jpg»)

        bardejov = ImageTk.PhotoImage(bard)

        label1 = Label(self, image=bardejov)

        label1.image = bardejov

        label1.place(x=20, y=20)

 

        rot = Image.open(«rotunda.jpg»)

        rotunda = ImageTk.PhotoImage(rot)

        label2 = Label(self, image=rotunda)

        label2.image = rotunda

        label2.place(x=40, y=160)

 

        minc = Image.open(«mincol.jpg»)

        mincol = ImageTk.PhotoImage(minc)

        label3 = Label(self, image=mincol)

        label3. image = mincol

        label3.place(x=170, y=50)

 

 

def main():

 

    root = Tk()

    root.geometry(«300×280+300+300»)

    app = Example()

    root.mainloop()

 

 

if __name__ == ‘__main__’:

    main()

В этом примере мы расположили три изображения при помощи абсолютного позиционирования. Мы использовали менеджер геометрии place.

from PIL import Image, ImageTk

from PIL import Image, ImageTk

Мы использовали Image и ImageTk из модуля PIL (Python Imaging Library).

style = Style()
style.configure(«TFrame», background=»#333″)

style = Style()

style.configure(«TFrame», background=»#333″)

При помощи стилей, мы изменили фон нашего окна на темно-серый.

bard = Image. open(«bardejov.jpg»)
bardejov = ImageTk.PhotoImage(bard)

bard = Image.open(«bardejov.jpg»)

bardejov = ImageTk.PhotoImage(bard)

Мы создали объект изображения и объект фото изображения из сохраненных ранее изображений в текущей рабочей директории.

label1 = Label(self, image=bardejov)

label1 = Label(self, image=bardejov)

Мы создали Label (ярлык) с изображением. Данные ярлыки могут содержать как изображения, так и текст.

Нам нужно сохранить ссылку на изображение, чтобы не потерять его если сборщик мусора (Garbage collector) его не закроет.

Ярлык размещен в рамке по координатам x=20 и y=20.

Tkinter pack() — размещение виджетов по горизонтали и вертикали

Менеджер геометрии pack() упорядочивает виджеты в горизонтальные и вертикальные блоки. Макетом можно управлять с помощью параметров fill, expand и side.

Пример создания кнопок в Tkinter

В следующем примере мы разместим две кнопки в нижнем правом углу нашего окна. Для этого мы воспользуемся менеджером pack.

from tkinter import Tk, RIGHT, BOTH, RAISED
from tkinter.ttk import Frame, Button, Style

class Example(Frame):

def __init__(self):
super().__init__()
self.initUI()

def initUI(self):
self.master.title(«Кнопки в kinter»)
self.style = Style()
self.style.theme_use(«default»)

frame = Frame(self, relief=RAISED, borderwidth=1)
frame.pack(fill=BOTH, expand=True)

self.pack(fill=BOTH, expand=True)

closeButton = Button(self, text=»Закрыть»)
closeButton.pack(side=RIGHT, padx=5, pady=5)
okButton = Button(self, text=»Готово»)
okButton.pack(side=RIGHT)

def main():

root = Tk()
root.geometry(«300×200+300+300»)
app = Example()
root.mainloop()

if __name__ == ‘__main__’:
main()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

from tkinter import Tk, RIGHT, BOTH, RAISED

from tkinter. ttk import Frame, Button, Style

 

 

class Example(Frame):

 

    def __init__(self):

        super().__init__()

        self.initUI()

 

    def initUI(self):

        self.master.title(«Кнопки в kinter»)

        self.style = Style()

        self.style.theme_use(«default»)

 

        frame = Frame(self, relief=RAISED, borderwidth=1)

        frame.pack(fill=BOTH, expand=True)

 

        self.pack(fill=BOTH, expand=True)

 

        closeButton = Button(self, text=»Закрыть»)

        closeButton.pack(side=RIGHT, padx=5, pady=5)

        okButton = Button(self, text=»Готово»)

        okButton.pack(side=RIGHT)

 

 

def main():

 

    root = Tk()

    root.geometry(«300×200+300+300»)

    app = Example()

    root.mainloop()

 

 

if __name__ == ‘__main__’:

    main()

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

У нас есть две рамки. Первая рамка – основная, а также вторая – дополнительная, которая растягивается в обе стороны и сдвигает две кнопки в нижнюю часть основной рамки. Кнопки находятся в горизонтальном контейнере и размещены в ее правой части.

frame = Frame(self, relief=RAISED, borderwidth=1)
frame.pack(fill=BOTH, expand=True)

frame = Frame(self, relief=RAISED, borderwidth=1)

frame.pack(fill=BOTH, expand=True)

Мы создали еще один виджет Frame. Этот виджет занимает практически все пространство окна. Мы изменяем границы рамки, чтобы сама рамка была видна. По умолчанию она плоская.

closeButton = Button(self, text=»Закрыть»)
closeButton.pack(side=RIGHT, padx=5, pady=5)

closeButton = Button(self, text=»Закрыть»)

closeButton.pack(side=RIGHT, padx=5, pady=5)

Кнопка closeButton создана. Она расположена в горизонтальном контейнере. Параметр side позволяет поместить кнопку в правой части горизонтальной полосы. Параметры padx и pady позволяют установить отступ между виджетами. Параметр padx устанавливает пространство между виджетами кнопки closeButton и правой границей корневого окна.

okButton.pack(side=RIGHT)

okButton.pack(side=RIGHT)

Кнопка okButton размещена возле closeButton с установленным отступом (padding) в 5 пикселей.

Создаем приложение для отзывов на Tkinter

Менеджер pack – это простой менеджер разметки. Его можно использовать для простых задач разметки. Чтобы создать более сложную разметку, необходимо использовать больше рамок, каждая из которых имеет собственный менеджер разметки.

from tkinter import Tk, Text, BOTH, X, N, LEFT
from tkinter. ttk import Frame, Label, Entry

class Example(Frame):

def __init__(self):
super().__init__()
self.initUI()

def initUI(self):
self.master.title(«Оставить отзыв»)
self.pack(fill=BOTH, expand=True)

frame1 = Frame(self)
frame1.pack(fill=X)

lbl1 = Label(frame1, text=»Заголовок», width=10)
lbl1.pack(side=LEFT, padx=5, pady=5)

entry1 = Entry(frame1)
entry1.pack(fill=X, padx=5, expand=True)

frame2 = Frame(self)
frame2.pack(fill=X)

lbl2 = Label(frame2, text=»Автор», width=10)
lbl2.pack(side=LEFT, padx=5, pady=5)

entry2 = Entry(frame2)
entry2.pack(fill=X, padx=5, expand=True)

frame3 = Frame(self)
frame3.pack(fill=BOTH, expand=True)

lbl3 = Label(frame3, text=»Отзыв», width=10)
lbl3.pack(side=LEFT, anchor=N, padx=5, pady=5)

txt = Text(frame3)
txt.pack(fill=BOTH, pady=5, padx=5, expand=True)

def main():

root = Tk()
root. geometry(«300×300+300+300»)
app = Example()
root.mainloop()

if __name__ == ‘__main__’:
main()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

from tkinter import Tk, Text, BOTH, X, N, LEFT

from tkinter.ttk import Frame, Label, Entry

 

 

class Example(Frame):

 

    def __init__(self):

        super().__init__()

        self.initUI()

 

    def initUI(self):

        self.master.title(«Оставить отзыв»)

        self.pack(fill=BOTH, expand=True)

 

        frame1 = Frame(self)

        frame1. pack(fill=X)

 

        lbl1 = Label(frame1, text=»Заголовок», width=10)

        lbl1.pack(side=LEFT, padx=5, pady=5)

 

        entry1 = Entry(frame1)

        entry1.pack(fill=X, padx=5, expand=True)

 

        frame2 = Frame(self)

        frame2.pack(fill=X)

 

        lbl2 = Label(frame2, text=»Автор», width=10)

        lbl2.pack(side=LEFT, padx=5, pady=5)

 

        entry2 = Entry(frame2)

        entry2.pack(fill=X, padx=5, expand=True)

 

        frame3 = Frame(self)

        frame3.pack(fill=BOTH, expand=True)

 

        lbl3 = Label(frame3, text=»Отзыв», width=10)

        lbl3.pack(side=LEFT, anchor=N, padx=5, pady=5)

 

        txt = Text(frame3)

        txt.pack(fill=BOTH, pady=5, padx=5, expand=True)

 

 

def main():

 

    root = Tk()

    root.geometry(«300×300+300+300»)

    app = Example()

    root. mainloop()

 

 

if __name__ == ‘__main__’:

    main()

На этом примере видно, как можно создать более сложную разметку с многочисленными рамками и менеджерами pack().

self.pack(fill=BOTH, expand=True)

self.pack(fill=BOTH, expand=True)

Первая рамка является базовой. На ней располагаются все остальные рамки. Стоит отметить, что даже при организации дочерних виджетов в рамках, мы управляем ими на базовой рамке.

frame1 = Frame(self)
frame1.pack(fill=X)

lbl1 = Label(frame1, text=»Заголовок», width=10)
lbl1.pack(side=LEFT, padx=5, pady=5)

entry1 = Entry(frame1)
entry1.pack(fill=X, padx=5, expand=True)

frame1 = Frame(self)

frame1.pack(fill=X)

 

lbl1 = Label(frame1, text=»Заголовок», width=10)

lbl1.pack(side=LEFT, padx=5, pady=5)

 

entry1 = Entry(frame1)

entry1. pack(fill=X, padx=5, expand=True)

Первые два виджета размещены на первой рамке. Поле для ввода данных растянуто горизонтально с параметрами fill и expand.

frame3 = Frame(self)
frame3.pack(fill=BOTH, expand=True)

lbl3 = Label(frame3, text=»Отзыв», width=10)
lbl3.pack(side=LEFT, anchor=N, padx=5, pady=5)

txt = Text(frame3)
txt.pack(fill=BOTH, pady=5, padx=5, expand=True)

frame3 = Frame(self)

frame3.pack(fill=BOTH, expand=True)

 

lbl3 = Label(frame3, text=»Отзыв», width=10)

lbl3.pack(side=LEFT, anchor=N, padx=5, pady=5)        

 

txt = Text(frame3)

txt.pack(fill=BOTH, pady=5, padx=5, expand=True)

В третьей рамке мы разместили ярлык и виджет для ввода текста. Ярлык закреплен по северной стороне anchor=N, а виджет текста занимает все остальное пространство.

Разметка grid() в Tkinter для создания калькулятора

Менеджер геометрии grid() в Tkinter используется для создания сетки кнопок для калькулятора.

from tkinter import Tk, W, E
from tkinter.ttk import Frame, Button, Entry, Style

class Example(Frame):

def __init__(self):
super().__init__()
self.initUI()

def initUI(self):
self.master.title(«Калькулятор на Tkinter»)

Style().configure(«TButton», padding=(0, 5, 0, 5), font=’serif 10′)

self.columnconfigure(0, pad=3)
self.columnconfigure(1, pad=3)
self.columnconfigure(2, pad=3)
self.columnconfigure(3, pad=3)

self.rowconfigure(0, pad=3)
self.rowconfigure(1, pad=3)
self.rowconfigure(2, pad=3)
self.rowconfigure(3, pad=3)
self.rowconfigure(4, pad=3)

entry = Entry(self)
entry.grid(row=0, columnspan=4, sticky=W+E)
cls = Button(self, text=»Очистить»)
cls.grid(row=1, column=0)
bck = Button(self, text=»Удалить»)
bck.grid(row=1, column=1)
lbl = Button(self)
lbl.grid(row=1, column=2)
clo = Button(self, text=»Закрыть»)
clo. grid(row=1, column=3)
sev = Button(self, text=»7″)
sev.grid(row=2, column=0)
eig = Button(self, text=»8″)
eig.grid(row=2, column=1)
nin = Button(self, text=»9″)
nin.grid(row=2, column=2)
div = Button(self, text=»/»)
div.grid(row=2, column=3)

fou = Button(self, text=»4″)
fou.grid(row=3, column=0)
fiv = Button(self, text=»5″)
fiv.grid(row=3, column=1)
six = Button(self, text=»6″)
six.grid(row=3, column=2)
mul = Button(self, text=»*»)
mul.grid(row=3, column=3)

one = Button(self, text=»1″)
one.grid(row=4, column=0)
two = Button(self, text=»2″)
two.grid(row=4, column=1)
thr = Button(self, text=»3″)
thr.grid(row=4, column=2)
mns = Button(self, text=»-«)
mns.grid(row=4, column=3)

zer = Button(self, text=»0″)
zer.grid(row=5, column=0)
dot = Button(self, text=».»)
dot.grid(row=5, column=1)
equ = Button(self, text=»=»)
equ. grid(row=5, column=2)
pls = Button(self, text=»+»)
pls.grid(row=5, column=3)

self.pack()

def main():
root = Tk()
app = Example()
root.mainloop()

if __name__ == ‘__main__’:
main()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

from tkinter import Tk, W, E

from tkinter.ttk import Frame, Button, Entry, Style

 

 

class Example(Frame):

 

    def __init__(self):

        super().__init__()

        self.initUI()

 

    def initUI(self):

        self.master.title(«Калькулятор на Tkinter»)

 

        Style().configure(«TButton», padding=(0, 5, 0, 5), font=’serif 10′)

 

        self.columnconfigure(0, pad=3)

        self.columnconfigure(1, pad=3)

        self.columnconfigure(2, pad=3)

        self.columnconfigure(3, pad=3)

 

        self.rowconfigure(0, pad=3)

        self.rowconfigure(1, pad=3)

        self.rowconfigure(2, pad=3)

        self.rowconfigure(3, pad=3)

        self.rowconfigure(4, pad=3)

 

        entry = Entry(self)

        entry.grid(row=0, columnspan=4, sticky=W+E)

        cls = Button(self, text=»Очистить»)

        cls.grid(row=1, column=0)

        bck = Button(self, text=»Удалить»)

        bck.grid(row=1, column=1)

        lbl = Button(self)

        lbl.grid(row=1, column=2)

        clo = Button(self, text=»Закрыть»)

        clo.grid(row=1, column=3)

        sev = Button(self, text=»7″)

        sev.grid(row=2, column=0)

        eig = Button(self, text=»8″)

        eig.grid(row=2, column=1)

        nin = Button(self, text=»9″)

        nin.grid(row=2, column=2)

        div = Button(self, text=»/»)

        div.grid(row=2, column=3)

 

        fou = Button(self, text=»4″)

        fou.grid(row=3, column=0)

        fiv = Button(self, text=»5″)

        fiv.grid(row=3, column=1)

        six = Button(self, text=»6″)

        six.grid(row=3, column=2)

        mul = Button(self, text=»*»)

        mul.grid(row=3, column=3)

 

        one = Button(self, text=»1″)

        one.grid(row=4, column=0)

        two = Button(self, text=»2″)

        two.grid(row=4, column=1)

        thr = Button(self, text=»3″)

        thr.grid(row=4, column=2)

        mns = Button(self, text=»-«)

        mns.grid(row=4, column=3)

 

        zer = Button(self, text=»0″)

        zer.grid(row=5, column=0)

        dot = Button(self, text=».»)

        dot.grid(row=5, column=1)

        equ = Button(self, text=»=»)

        equ.grid(row=5, column=2)

        pls = Button(self, text=»+»)

        pls.grid(row=5, column=3)

 

        self.pack()

 

 

def main():

    root = Tk()

    app = Example()

    root.mainloop()

 

 

if __name__ == ‘__main__’:

    main()

Менеджер grid() используется для организации кнопок в контейнере рамки.

Style().configure(«TButton», padding=(0, 5, 0, 5),
font=’serif 10′)

Style().configure(«TButton», padding=(0, 5, 0, 5),

    font=’serif 10′)

Мы настроили виджет кнопки так, чтобы отображался специфический шрифт и применялся отступ (padding) в 3 пикселя.

self.columnconfigure(0, pad=3)

self.rowconfigure(0, pad=3)

self.columnconfigure(0, pad=3)

…        

self.rowconfigure(0, pad=3)

Мы использовали методы columnconfigure() и rowconfigure() чтобы создать определенное пространство в сетке строк и столбцов. Благодаря этому шагу мы разделяем кнопки определенным пустым пространством.

entry = Entry(self)
entry.grid(row=0, columnspan=4, sticky=W+E)

entry = Entry(self)

entry.grid(row=0, columnspan=4, sticky=W+E)

Виджет графы ввода – это место, где будут отображаться цифры. Данный виджет расположен в первом ряду и охватывает все четыре столбца. Виджеты могут не занимать все пространство, которое выделяется клетками в созданной сетке.

Параметр sticky расширяет виджет в указанном направлении. В нашем случае, мы можем убедиться, что наш виджет графы ввода был расширен слева направо W+E (восток-запад).

cls = Button(self, text=»Очистить»)
cls.grid(row=1, column=0)

cls = Button(self, text=»Очистить»)

cls.grid(row=1, column=0)

Кнопка очистки установлена во второй строке и первом столбце. Стоит отметить, что строки и столбцы начинаются с нуля.

Метод pack() показывает виджет рамки и дает ей первоначальный размер. Если дополнительные параметры не указываются, размер будет таким, чтобы все дочерние виджеты могли поместиться. Этот метод компонует виджет рамки в верхнем корневом окне, которое также является контейнером. Менеджер grid() используется для организации кнопок в виджете рамки.

Пример создания диалогового окна в Tkinter

Следующий пример создает диалоговое окно, используя менеджер геометрии grid.

from tkinter import Tk, Text, BOTH, W, N, E, S
from tkinter.ttk import Frame, Button, Label, Style

class Example(Frame):

def __init__(self):
super().__init__()
self.initUI()

def initUI(self):

self.master.title(«Диалоговое окно в Tkinter»)
self.pack(fill=BOTH, expand=True)

self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)

lbl = Label(self, text=»Окна»)
lbl.grid(sticky=W, pady=4, padx=5)

area = Text(self)
area.grid(row=1, column=0, columnspan=2, rowspan=4, padx=5, sticky=E+W+S+N)

abtn = Button(self, text=»Активир.»)
abtn.grid(row=1, column=3)

cbtn = Button(self, text=»Закрыть»)
cbtn.grid(row=2, column=3, pady=4)

hbtn = Button(self, text=»Помощь»)
hbtn.grid(row=5, column=0, padx=5)

obtn = Button(self, text=»Готово»)
obtn.grid(row=5, column=3)

def main():

root = Tk()
root.geometry(«350×300+300+300»)
app = Example()
root.mainloop()

if __name__ == ‘__main__’:
main()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

from tkinter import Tk, Text, BOTH, W, N, E, S

from tkinter.ttk import Frame, Button, Label, Style

 

 

class Example(Frame):

 

    def __init__(self):

        super().__init__()

        self.initUI()

 

 

    def initUI(self):

 

        self.master.title(«Диалоговое окно в Tkinter»)

        self.pack(fill=BOTH, expand=True)

 

        self.columnconfigure(1, weight=1)

        self.columnconfigure(3, pad=7)

        self.rowconfigure(3, weight=1)

        self.rowconfigure(5, pad=7)

 

        lbl = Label(self, text=»Окна»)

        lbl.grid(sticky=W, pady=4, padx=5)

 

        area = Text(self)

        area.grid(row=1, column=0, columnspan=2, rowspan=4, padx=5, sticky=E+W+S+N)

 

        abtn = Button(self, text=»Активир.»)

        abtn.grid(row=1, column=3)

 

        cbtn = Button(self, text=»Закрыть»)

        cbtn.grid(row=2, column=3, pady=4)

 

        hbtn = Button(self, text=»Помощь»)

        hbtn.grid(row=5, column=0, padx=5)

 

        obtn = Button(self, text=»Готово»)

        obtn.grid(row=5, column=3)

 

 

def main():

 

    root = Tk()

    root.geometry(«350×300+300+300»)

    app = Example()

    root.mainloop()

 

 

if __name__ == ‘__main__’:

    main()

В этом примере мы использовали виджет ярлыкатекстовой виджет и четыре кнопки.

self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)

self.columnconfigure(1, weight=1)

self.columnconfigure(3, pad=7)

self.rowconfigure(3, weight=1)

self.rowconfigure(5, pad=7)

Мы добавили небольшое пространство между виджетами в сетке. Параметр weight создает возможность расширения второго столбца и четвертого ряда. В этом ряду и столбце находится текстовой виджет, поэтому оставшееся пространство заполняет данный виджет.

lbl = Label(self, text=»Окна»)
lbl.grid(sticky=W, pady=4, padx=5)

lbl = Label(self, text=»Окна»)

lbl.grid(sticky=W, pady=4, padx=5)

Виджет ярлыка также создается и помещается в сетку. Если не указываются ряд и столбец, тогда он займет первый ряд и столбец. Ярлык закрепляется у западной части окна sticky=W и имеет определенные отступы вокруг своих границ.

area = Text(self)
area.grid(row=1, column=0, columnspan=2, rowspan=4,
padx=5, sticky=E+W+S+N)

area = Text(self)

area.grid(row=1, column=0, columnspan=2, rowspan=4,

    padx=5, sticky=E+W+S+N)

Создается текстовый виджет и помещается во второй ряд и первый столбец. Он охватывает два столбца и четыре строки.

Между виджетом и левым краем корневого окна присутствует пространство в 4 пикселя. Также, виджет закреплен около всех четырех сторон. Поэтому, когда окно расширяется, виджеты текстов увеличиваются во всех направлениях.

abtn = Button(self, text=»Активир.»)
abtn.grid(row=1, column=3)

cbtn = Button(self, text=»Закрыть»)
cbtn.grid(row=2, column=3, pady=4)

abtn = Button(self, text=»Активир.»)

abtn.grid(row=1, column=3)

 

cbtn = Button(self, text=»Закрыть»)

cbtn.grid(row=2, column=3, pady=4)

Эти две кнопки находятся возле текстового виджета.

hbtn = Button(self, text=»Помощь»)
hbtn.grid(row=5, column=0, padx=5)

obtn = Button(self, text=»Готово»)
obtn.grid(row=5, column=3)

hbtn = Button(self, text=»Помощь»)

hbtn.grid(row=5, column=0, padx=5)

 

obtn = Button(self, text=»Готово»)

obtn.grid(row=5, column=3)

Эти две кнопки находятся под текстовым виджетом. Кнопка «Помощь» расположена в первом столбце, а кнопка «Готово» в последнем столбце.
В этой части изучения Tkinter мы рассказали о работе с разметкой виджетов.

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.

E-mail: [email protected]

Образование
Universitatea Tehnică a Moldovei (utm.md)

  • 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»

Пакуем байты на Python: struct

Кто сказал, что нельзя делать низкоуровневые вещи на Python? Конечно, можно. Давайте научимся упаковывать данные из Python в байты и распаковывать их обратно.

Встроенный модуль struct как раз создан для этих целей. В низкоуровневом деле важны детали, а именно размер каждого элемента данных, их порядок в структуре, а также порядок байт для многобайтовых типов данных. Для определения этих деталей модуль struct вводит форматные строки (не путать с str.format, там другой формат).

Начнем с простого примера:

>>> import struct
>>> struct.pack("hhl", 1, 2, 3)
b'\x01\x00\x02\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00'

Здесь происходит вот что. Мы берем три числа: 1, 2, 3 и пакуем их в байты, таким образом, что первое и второе числа трактуются как тип short int (4 байта на моей машине), а последнее, как long int (8 байт на моей машине). Это типы не из Python, а из языка Си. Ознакомьтесь с типами языка Си, если хотите понимать, что они из себя представляют и какой размер в байтах имеют.

Обратная распаковка байт в кортеж значений по заданному формату:

>>> struct.unpack("hhl", b'\x01\x00\x02\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00')
(1, 2, 3)

Форматы запаковки и распаковки должны совпадать, иначе данные будут неправильно интерпретированы или испорчены, или же вообще возникнет ошибка из-за того, что размер данных не подходит под ожидаемый формат (struct.error):

>>> struct.unpack("hhl", b'\x01\x02\x03')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
struct.error: unpack requires a buffer of 16 bytes

Обратите внимание, что я выше писал, что размер элемента «h» – 4 байта именно на моей машине. Может статься так, что на машине с другим процессором, архитектурой или просто с другой версией ОС размер типа будет другой. Для 32 битных систем, это обычно будет 2 байта.

Но, что если данных передаются по сети или через носители информации между системами с разной или неизвестной заранее архитектурой? Конечно, у struct есть средства на такие случаи. Первый символ форматной строки обозначит порядок байт. Обратите внимание на таблицу:

Символ Порядок байт Размеры типов Выравнивание
@ нативный нативный нативное
= нативный стандартные нет
< little-endian стандартные нет
> big-endian стандартные нет
! сетевой
(= big-endian)
стандартные нет

Нативный – значит родной для конкретно вашей машины и системы. По умолчанию порядок байт и размер типов данных как раз нативный (символ @).

Стандартный размер – размер, который фиксирован стандартом и не зависит от текущей платформы. Например, char всегда 1 байт, а int – 4 байта. Если мы планируем распространять запакованные байты, мы должны гарантировать, что размер типов будет всегда стандартный. Для этого подходит любой из символов «=«, «<«, «>«, «!» в начале форматной строки.

Little-endian и big-endian

Little-endian и big-endian – это два основных порядка байт. Представим, что у нас есть короткое целое (short int), и оно занимает два (2) байта. Какой из байтов должен идти сначала, а какой в конце?

В big-endian порядок от старшего байта к младшему. В little-endian порядок от младшего байта к старшему. Как узнать на Python какой порядок байт в системе:

>>> import sys
>>> sys.byteorder
'little'

Давайте наглядно посмотрим как пакуются байты при разных порядках. Для числа 258 в форме short младший байт будет = 2, а старший = 1:

258 = 2*20 + 1*28

>>> struct.pack("<h", 258)  # little-endian
b'\x02\x01'
>>> struct.pack(">h", 258)  # big-endian
b'\x01\x02'

Как видите порядок байт противоположный для разных случаев.

В сетевых протоколах принято использовать big-endian (символ «!» – псевдоним к «>«), а на большинстве современных настольных систем используется little-endian.

Таблица типов данных

Теперь ознакомимся с таблицей типов данных, которая дает соответствие символу форматной строки (код преобразования) с Си-типом данных, Python-типом данных и стандартный размером. Еще раз: стандартный размер будет только, если задан первый символ как «<«, «>«, «!» или «=«. Для «@» или по умолчанию – размер данных определяется текущей системой (платформо-зависимо).

Символ Тип в языке Си Python тип Станд. размер
x байт набивки нет значения
c char bytes длины 1 1
b signed char integer 1
B unsigned char integer 1
? _Bool bool 1
h short integer 2
H unsigned short integer 2
i int integer 4
I unsigned int integer 4
l long integer 4
L unsigned long integer 4
q long long integer 8
Q unsigned long long integer 8
n ssize_t integer зависит
N size_t integer зависит
e «половинный float« float 2
f float float 4
d double float 8
s char[] bytes указывается явно
p char[] — строка из Паскаля bytes указывается явно

Коды «e«, «f«, «d» используют бинарный формат IEEE-754.

Код «x» это просто байт набивки. Он не попадает в распакованные данные, а нужен, чтобы выравнивать данные. «x» при запаковке забиваются пустыми байтами. Пример: «пусто-число-пусто-пусто-число-пусто»:

>>> struct.pack(">xBxxBx", 255, 128)
b'\x00\xff\x00\x00\x80\x00'

>>> struct.unpack('>xBxxBx', b'\x00\xff\x00\x00\x80\x00')
(255, 128)

О форматной строке

Если в форматной строке перед символом кода – число, то значит этот символ повторяется столько раз, сколько указывает число. Два кусочка кода аналогичны:

>>> struct.pack(">3h", 1, 2, 3)
b'\x00\x01\x00\x02\x00\x03'

>>> struct.pack(">hhh", 1, 2, 3)
b'\x00\x01\x00\x02\x00\x03'

Для строк (коды «s» и «p«) надо указывать число байт – длину строки, иначе будет считаться 1 байт:

>>> struct.pack("ss", b"abc", b"XYZW")  # не указал длину - потерял байты
b'aX'

>>> struct.pack("3s4s", b"abc", b"XYZW")
b'abcXYZW'

10s – одна 10-символьная строка, а 10c – 10 отдельных символов:

>>> struct.unpack('10c', b'abracadabr')
(b'a', b'b', b'r', b'a', b'c', b'a', b'd', b'a', b'b', b'r')

>>> struct.unpack('10s', b'abracadabr')
(b'abracadabr',)

Можно вставлять пробелы между отдельными элементами форматной строки (но нельзя отделать число от символа). Пробелы игнорируются при чтении строки и нужны для удобства чтения кода программистом:

>>> struct.pack('>6sh?', b'python', 65, True)
b'python\x00A\x01'

>>> struct.pack('> 6s h ?', b'python', 65, True)  # тоже, но с пробелами
b'python\x00A\x01'

>>> struct.unpack('> 6s h ?', b'python\x00A\x01')
(b'python', 65, True)

Полезности

Можно вычислить размер данных из форматной строки без фактической запаковки или распаковки данных:

>>> struct.calcsize('> 6s h ?')
9

Удобно распаковывать байты прямо в именованные кортежи:

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> record = b'raymond   \x32\x12\x08\x01\x08'
>>> Student._make(struct.unpack('<10sHHb', record))
Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)

Запаковка в буффер со смещением struct.pack_into(formatbufferoffsetv1v2...):

>>> buffer = bytearray(40)
>>> struct.pack_into('h l', buffer, 10, 3432, 340840)
>>> buffer
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\r\x00\x00\x00\x00\x00\x00h4\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
>>>

Распаковка из буффера со смещением:

>>> x, y = struct.unpack_from('h l', buffer, 10)
>>> x, y
(3432, 340840)

Распаковка нескольких однотипных структур:

>>> chunks = struct.pack('hh', 10, 20) * 5  
>>> chunks  # 5 одинаковых штук
b'\n\x00\x14\x00\n\x00\x14\x00\n\x00\x14\x00\n\x00\x14\x00\n\x00\x14\x00'

>>> [(x, y) for x, y in struct.iter_unpack('hh', chunks)]
[(10, 20), (10, 20), (10, 20), (10, 20), (10, 20)]

Специально для канала @pyway. Подписывайтесь на мой канал в Телеграм @pyway 👈 




5 860

Python | Позиционирование элементов

Позиционирование элементов

Последнее обновление: 13.05.2017

Метод pack

Для позиционирования элементов в окне применяются различные способы, и самый простой способ представляет вызов у элемента метода pack().
Этот метод принимает следующие параметры:

  • expand: если равно True, то виджет заполняет все пространство контейнера.

  • fill: определяет, будет ли виджет растягиваться, чтобы заполнить свободное пространство вокруг. Этот параметр может принимать следующие значения:
    NONE (по умолчанию, элемент не растягивается), X (элемент растягивается только по горизонтали), Y (элемент растягивается только по вертикали) и
    BOTH (элемент растягивается по вертикали и горизонтали).

  • side: выравнивает виджет по одной из сторон контейнера. Может принимать значения: TOP (по умолчанию, выравнивается по верхней стороне контейнера),
    BOTTOM (выравнивание по нижней стороне), LEFT (выравнивание по левой стороне), RIGHT (выравнивание по правой стороне).

Например, растянем кнопку на всю форм, используя параметры expand и fill:


from tkinter import *

root = Tk()
root.title("GUI на Python")
root.geometry("300x250")

btn1 = Button(text="CLICK ME", background="#555", foreground="#ccc",
              padx="15", pady="6", font="15")
btn1.pack(expand = True, fill=BOTH)

root.mainloop()

Используем параметр side:


from tkinter import *

root = Tk()
root.title("GUI на Python")
root.geometry("300x250")

btn1 = Button(text="BOTTOM", background="#555", foreground="#ccc",
              padx="15", pady="6", font="15")
btn1.pack(side=BOTTOM)

btn2 = Button(text="RIGHT", background="#555", foreground="#ccc",
             padx="15", pady="6", font="15")
btn2.pack(side=RIGHT)

btn3 = Button(text="LEFT", background="#555", foreground="#ccc",
             padx="15", pady="6", font="15")
btn3.pack(side=LEFT)

btn4 = Button(text="TOP", background="#555", foreground="#ccc",
             padx="15", pady="6", font="15")
btn4.pack(side=TOP)

root.mainloop()

Комбинируя параметры side и fill, можно растянуть элемент по вертикали:


btn1 = Button(text="CLICK ME", background="#555", foreground="#ccc",
              padx="15", pady="6", font="15")
btn1.pack(side=LEFT, fill=Y)

Метод place

Метод place() позволяет более точно настроить параметры позиционирования. Он принимает следующие параметры:

  • height и width: устанавливают соответственно высоту и ширину элемента в пикселях

  • relheight и relwidth: также задают соответственно высоту и ширину элемента, но в качестве значения
    используется число float в промежутке между 0.0 и 1.0, которое указывает на долю от высоты и ширины родительского контейнера

  • x и y: устанавливают смещение элемента по горизонтали и вертикали в пикселях соответственно относительно верхнего левого угла контейнера

  • relx и rely: также задают смещение элемента по горизонтали и вертикали, но в качестве
    значения используется число float в промежутке между 0.0 и 1.0, которое указывает на долю от высоты и ширины родительского контейнера

  • bordermode: задает формат границы элемента. Может принимать значение INSIDE (по умолчанию) и OUTSIDE

  • anchor: устанавливает опции растяжения элемента. Может принимать значения n, e, s, w, ne, nw, se, sw, c, которые являются сокращениями от Noth(север — вверх),
    South (юг — низ), East (восток — правая сторона), West (запад — левая сторона) и Center (по центру). Например, значение nw указывает на верхний левый угол

Например, разместим кнопку с шириной 130 пикселей и высотой 30 пикселей в центре окна:


from tkinter import *

clicks = 0


def click_button():
    global clicks
    clicks += 1
    btn.config(text="Clicks {}".format(clicks))

root = Tk()
root.title("GUI на Python")
root.geometry("300x250")


btn = Button(text="Clicks 0", background="#555", foreground="#ccc",
             padx="20", pady="8", font="16", command=click_button)
btn.place(relx=.5, rely=.5, anchor="c", height=30, width=130, bordermode=OUTSIDE)

root.mainloop()

Следует заметить, что при использовании метода place() не надо использовать метод pack(), чтобы сделать элемент видимым.

Или разместим три кнопки:


from tkinter import *

root = Tk()
root.title("GUI на Python")
root.geometry("300x250")

btn1 = Button(text="x=10, y=20", background="#555", foreground="#ccc", padx="14", pady="7", font="13")
btn1.place(x=10, y=20)

btn2 = Button(text="x=50, y=100", background="#555", foreground="#ccc", padx="14", pady="7", font="13")
btn2.place(x=50, y=100)

btn3 = Button(text="x=140, y=160", background="#555", foreground="#ccc", padx="14", pady="7", font="13")
btn3.place(x=140, y=160)

root.mainloop()

Метод grid

Метод grid применяет другой подход к позиционированию элементов, нежели метод place, позволяя поместить элемент в определенную ячейку условной сетки или грида.

Метод grid применяет следующие параметры:

  • column: номер столбца, отсчет начинается с нуля

  • row: номер строки, отсчет начинается с нуля

  • columnspan: сколько столбцов должен занимать элемент

  • rowspan: сколько строк должен занимать элемент

  • ipadx и ipady: отступы по горизонтали и вертикали соответственно от границ элемента до его текста

  • padx и pady: отступы по горизонтали и вертикали соответственно от границ ячейки грида до границ элемента

  • sticky: выравнивание элемента в ячейке, если ячейка больше элемента. Может принимать значения n, e, s, w, ne, nw, se, sw, которые указывают
    соответствующее направление выравнивания

Например, определим грид из 9 кнопок:


from tkinter import *

root = Tk()
root.title("GUI на Python")
root.geometry("300x250")

for r in range(3):
    for c in range(3):
        btn = Button(text="{}-{}".format(r,c))
        btn.grid(row=r, column=c, ipadx=10, ipady=6, padx=10, pady=10)

root.mainloop()

python pack() и grid() методы вместе

Я новичок в python, так что, пожалуйста, простите мою Нуб-Несс. Я пытаюсь создать строку состояния в нижней части окна приложения, но, похоже, каждый раз, когда я использую методы pack() и grid() вместе в одном файле, главное окно приложения не открывается. Когда я закомментирую строку с надписью statusbar.pack(side = BOTTOM, fill = X), мое окно приложения откроется нормально, но если я оставлю его в нем, то нет, а также если я закомментирую любые строки, использующие метод сетки, окно откроется со строкой состояния. Похоже, я могу использовать только pack() или grid(), но не оба. Я знаю, что смогу использовать оба метода. Есть предложения? Вот код:

from Tkinter import *
import tkMessageBox

def Quit():
 answer = tkMessageBox.askokcancel('Quit', 'Are you sure?')
 if answer:
    app.destroy()

app = Tk()
app.geometry('700x500+400+200')
app.title('Title')

label_1 = Label(text = "Enter number")
label_1.grid(row = 0, column = 0)
text_box1 = DoubleVar() 
input1 = Entry(app, textvariable = text_box1)
input1.grid(row = 0, column = 2)

statusbar = Label(app, text = "", bd = 1, relief = SUNKEN, anchor = W)
statusbar.pack(side = BOTTOM, fill = X)

startButton = Button(app, text = "Start", command = StoreValues).grid(row = 9, column = 2,  padx = 15, pady = 15)

app.mainloop() 

Любая помощь приветствуется! Спасибо!

python

grid

tkinter

pack

Поделиться

Источник


terence vaughn    

24 июня 2013 в 02:10

2 ответа


  • Использование .pack() и .grid() одновременно с tkinter

    У меня есть программа с некоторыми Label() виджетами, некоторыми Button() виджетами, некоторыми Text() виджетами и несколькими Entry() виджетами. Пару лет назад у меня не было меток, и у меня было меньше виджетов Entry(), и я смешал .pack() и .grid(), как было удобно, и все было в порядке. Мне…

  • Tkinter: pack()ing фреймы, использующие grid()

    Я работаю над UI для отображения данных applet. Я начал с учебника и с тех пор расширил его далеко за рамки учебника, но некоторые устаревшие биты остались от учебника, которые теперь вызывают у меня трудности. В частности, в отношении pack() и grid() . Следуя учебнику, я определил объект class…



12

Вы не можете использовать как pack , так и grid для виджетов, имеющих один и тот же мастер. Первый из них будет регулировать размер виджета. Другой увидит изменение и изменит размер всего, чтобы соответствовать его собственным ограничениям. Первый увидит эти изменения и снова изменит размер всего, чтобы соответствовать его ограничениям. Другой увидит изменения, и так до бесконечности. Они застрянут в вечной борьбе за превосходство.

Хотя технически это возможно, если вы действительно знаете, что делаете, вы не можете смешивать их в одном контейнере . Вы можете смешивать их все, что хотите, в своем приложении в целом, но для данного контейнера (обычно фрейма) вы можете использовать только один для управления непосредственным содержимым контейнера.

Очень распространенная техника состоит в том, чтобы разделить ваш GUI на части. В вашем случае у вас есть нижняя строка состояния и верхняя область «main». Итак, упакуйте строку состояния вдоль нижней части и создайте рамку, которую вы упакуете над ней для основной части GUI. Затем все остальное имеет основной фрейм в качестве своего родителя,и внутри этого фрейма вы можете использовать сетку, пакет или что угодно.

Поделиться


Bryan Oakley    

24 июня 2013 в 02:54



2

Да, именно так. В следующем примере я разделил свою программу на 2 кадра. frame1 обслуживает меню/Панель инструментов и использует методы pack(), в которых frame2 используется для создания учетных данных страницы входа и использует методы grid().

from tkinter import *

def donothing():
    print ('IT WORKED')
root=Tk()
root.title(string='LOGIN PAGE')

frame1=Frame(root)
frame1.pack(side=TOP,fill=X)

frame2=Frame(root)
frame2.pack(side=TOP, fill=X)

m=Menu(frame1)
root.config(menu=m)

submenu=Menu(m)
m.add_cascade(label='File',menu=submenu)
submenu.add_command(label='New File', command=donothing)
submenu.add_command(label='Open', command=donothing)
submenu.add_separator()
submenu.add_command(label='Exit', command=frame1.quit)


editmenu=Menu(m)
m.add_cascade(label='Edit', menu=editmenu)
editmenu.add_command(label='Cut',command=donothing)
editmenu.add_command(label='Copy',command=donothing)
editmenu.add_command(label='Paste',command=donothing)
editmenu.add_separator()
editmenu.add_command(label='Exit', command=frame1.quit)


# **** ToolBar *******

toolbar=Frame(frame1,bg='grey')
toolbar.pack(side=TOP,fill=X)
btn1=Button(toolbar, text='Print', command=donothing)
btn2=Button(toolbar, text='Paste', command=donothing)
btn3=Button(toolbar, text='Cut', command=donothing)
btn4=Button(toolbar, text='Copy', command=donothing)
btn1.pack(side=LEFT,padx=2)
btn2.pack(side=LEFT,padx=2)
btn3.pack(side=LEFT,padx=2)
btn4.pack(side=LEFT,padx=2)

# ***** LOGIN CREDENTIALS ******
label=Label(frame2,text='WELCOME TO MY PAGE',fg='red',bg='white')
label.grid(row=3,column=1)

label1=Label(frame2,text='Name')
label2=Label(frame2,text='Password')
label1.grid(row=4,column=0,sticky=E)
label2.grid(row=5,column=0,sticky=E)

entry1=Entry(frame2)
entry2=Entry(frame2)
entry1.grid(row=4,column=1)
entry2.grid(row=5,column=1)

chk=Checkbutton(frame2,text='KEEP ME LOGGED IN')
chk.grid(row=6,column=1)

btn=Button(frame2,text='SUBMIT')
btn.grid(row=7,column=1)




# **** StatusBar ******************

status= Label(root,text='Loading',bd=1,relief=SUNKEN,anchor=W)
status.pack(side=BOTTOM, fill=X)

Поделиться


Ary    

08 мая 2017 в 06:01


Похожие вопросы:

Разница между менеджерами геометрии «grid» и «pack»

В чем основное различие между менеджерами геометрии Tkinter grid и pack ? Что вы используете для своих проектов ? Если grid лучше выровнять объект, то какова основная цель pack ?

Решение использовать оба метода .pack() и .grid() в одном и том же окне tkinter?

Поэтому я играл с виджетами в Tkinter и из-за проблемы (которая была решена на этом форуме) Я понимаю, что у вас не может быть методов .pack() и .grid() для организации разных виджетов в одном окне….

Python tkinter: как применить Pack() к объекту

Итак, я пытаюсь сделать GUI на python, используя tkinter в первый раз, но у меня возникли проблемы с атрибутом Pack() . Мой код для GUI до сих пор выглядит следующим образом: mainframe = tk.Tk()…

Использование .pack() и .grid() одновременно с tkinter

У меня есть программа с некоторыми Label() виджетами, некоторыми Button() виджетами, некоторыми Text() виджетами и несколькими Entry() виджетами. Пару лет назад у меня не было меток, и у меня было…

Tkinter: pack()ing фреймы, использующие grid()

Я работаю над UI для отображения данных applet. Я начал с учебника и с тех пор расширил его далеко за рамки учебника, но некоторые устаревшие биты остались от учебника, которые теперь вызывают у…

Почему вы не можете использовать функцию ‘pack’ и ‘grid в одном коде

Я знаю, что вы не можете использовать pack и grid вместе, но почему? Почему это вызывает ошибку? _tkinter.TclError: cannot use geometry manager pack inside . which already has slaves managed by grid

виджет ввода и метка не являются worling, когда я использую grid(). Но когда я использую pack() этикетка печатается

from tkinter import * root=Tk() lab1=Label(root,text=Restaurant Management System) lab1.config(font=(Courier, 44)) lab1.pack(side=TOP) lab2=Label(root,text=Meals) e2=Entry(root) lab2.grid(row=0)…

Различия в pack() и grid() tkinter

хороший день. Изучение tkinter, использование Python 3.5. Для начала я добился некоторого успеха, используя pack() для кадров в root(), а затем использовал grid() внутри упакованных кадров. Затем я…

Вопрос о выстраивании кадров в Tkinter внутри сетки, попытке достичь идентичных результатов с .grid() и .pack() внутри кадра

Новичок в python и получающий много отличной информации с этого сайта. Я создаю диаграмму с .grid(), а затем снова с кадрами в .pack() в качестве упражнения и смотрю, смогу ли я получить идентичные…

В каких случаях Tkinter grid() нельзя смешивать с pack()?

Я хочу устранить странное дополнительное пространство, которое, кажется, сопротивляется любой настройке размера в моем макете при использовании только grid() , но вызов pack() иногда делает вещи еще…

Пакеты — Python: Основы

Python: Основы

Мы уже знаем, что в Python код хранится в отдельных файлах, называемых модулями. Но если начать делить код достаточно большого проекта на модули, то довольно быстро может возникнуть желание сгруппировать несколько модулей «по смыслу». Или же мы захотим вынести часть модулей из проекта с целью их использования в других проектах. Для объединения модулей в группы служат пакеты (packages).

Итак, пакет — это директория (далее «каталог») с файлами модулей, имеющая имя в формате «snake_case» и содержащая, помимо прочего, специальный модуль с именем «__init__.py«. Именно наличие этого специального файла подсказывает интерпретатору Python, что каталог следует воспринимать именно как пакет.

Простейший пакет

Давайте рассмотрим пример простейшего пакета. Пусть пакет состоит из каталога package и модуля __init__.py внутри этого каталога:

package/
└── __init__.py

Файл __init__.py пусть содержит код:

# file __init__.py
NAME = 'super_package'

Это, хотя и небольшой, но уже полноценный пакет. Его можно импортировать так же, как мы импортировали бы модуль:

import package

print(package.NAME)

Заметьте — мы не импортировали файл __init__.py непосредственно. При первом обращении к пакету Python автоматически импортирует модуль __init__.py в этом пакете. Поэтому, очевидно, нельзя импортировать «просто каталог» — ведь каталог без файла __init__.py не будет полноценным пакетом!

Содержимое пакета

С простым пакетом всё ясно — его можно использовать как модуль. Но давайте уже перейдём к группировке в пакете нескольких модулей! Для этого в пакет положим ещё два модуля:

package/
├── constants.py
├── functions.py
└── __init__.py

Содержимое модуля constants.py:

# file constants.py
PERSON = 'Alice'

Содержимое модуля functions.py:

# file functions.py
def greet(who):
    print('Hello, ' + who + '!')

Когда пакет содержит другие модули, кроме __init__.py, то их можно импортировать по их именам. В главе про модули упоминались два варианта импортирования: квалифицированный импорт и импортирование отдельных определений. Квалифицированный импорт в данном случае будет выглядеть так:

import package.functions
import package.constants

package.functions.greet(package.constants.PERSON)  # => Hello, Alice!

Этот вариант самый понятный: в строчке вызова функции greet сразу видно, откуда пришла функция, а откуда — её аргумент. Но писать имя пакета и имя модуля каждый раз — утомительно! Давайте импортируем саму функцию и аргумент:

from package.functions import greet
from package.constants import PERSON

greet(PERSON)  # => Hello, Alice!

Так строчка вызова функции выглядит гораздо лучше! Но помните, что тому, кто будет читать этот код в дальнейшем, потребуется посмотреть в блок импортов, чтобы узнать, откуда функция и константа появились.

Пакеты и импорты

Импорты в Python бывают двух видов: абсолютные и относительные. Понимание разницы становится особенно важным, когда вы начинаете работать с пакетами.

Абсолютные импорты

Абсолютный импорт выглядит как указание полного пути до модуля, включающего все пакеты и подпакеты (subpackages) — да, любой пакет может содержать не только модули, но и вложенные пакеты! Полные пути гарантируют однозначность: интерпретатору всегда понятно, что и откуда импортируется, и читать такие импорты проще.

Относительные импорты

Относительные импорты выглядят так:

from . import module
from .module import function
from .subpackage.module import CONSTANT

Здесь точка означает текущую директорию для модуля, который и осуществляет импорт. К примеру, импорт из .module означают импорт из модуля, находящегося в той же директории, которая содержит модуль с данным импортом. Звучит сложновато? Так и есть! Авторы языка тоже так считают, поэтому уже сейчас относительные импорты лишены части возможностей, которые были доступны в более ранних версиях языка (да, раньше было ещё сложнее!).

Какие же импорты использовать?

Я придерживаюсь мнения большинства: нужно всегда использовать абсолютные импорты! Даже если вы внутри одного пакета один модуль импортируете в другой. Да, при использовании абсолютных импортов приходится писать чуть больше. Но понятность кода — слишком полезное свойство, чтобы от него отказываться!


Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >

Нашли опечатку или неточность?

Выделите текст, нажмите
ctrl + enter
и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Github Students Pack — бонусы студентам-программистам Python

Программа Github Students Pack рассчитана на студентов, которые не могут себе позволить использование дорогостоящих подписок на платные сервисы для разработки.

В этой статье я собрал вкусности, которые очень сильно пригодятся студентам, создающим проекты на Python.

Чтобы получить эти бонусы, нужно зарегистрироваться на github, зайти на страницу Github Students Pack и запросить доступ.

Если у вас есть почта в зоне .edu (некоторые институты ее выдают), то доступ даётся автоматически.

Если же нет, нужно будет отправить скан студенческого. На странице Github Students Pack будут подробные инструкции.

Редакторы кода

  • repl.it — облачный редактор кода для более чем полусотни языков программирования, в том числе и Python. Hacker plan (с безлимитными приватными репозиториями) на год для студентов.

Мониторинг

  • honeybadger.io — мониторинг uptime, exception, cron jobs приложения. Small account на год для студентов.
  • sentry.io — мониторинг ошибок в приложении. 500000 событий в месяц (вместо 5000 на бесплатном плане), неограниченное количество проектов на всё время обучения.

Доменные имена

Хостинг и сервера

  • DigitalOcean — VPS и сопутствующие услуги. Купон на 50$ для новых пользователей (запрашивать на github).
  • Microsoft Azure — сервисы, утилиты и машины для разработчиков. Купон на 100$ для студентов (запрашивать на github).
  • Heroku — облачная PaaS-платформа, поддерживающая ряд языков программирования (в том числе и Python). Один бесплатный Hobby Dyno сервер на 2 года для студентов.
  • Amazon Web Services — хостинг, VPS, облачные вычисления. До 110$ для студентов.

Другое

  • github.com — GitHub Pro: неограниченное количество приватных репозиториев на всё время обучения.
  • Travis CI — распределённый веб-сервис для сборки и тестирования программного обеспечения. Бесплатные приватные репозитории на всё время обучения.
  • bettercodehub.com — проверка качества кода в github-репозиториях. Individual license (возможность анализа приватных репозиториев) для студентов.

Полный список бонусов можно посмотреть на https://education.github.com/pack (список партнеров постоянно пополняется!)

Для вставки кода на Python в комментарий заключайте его в теги <pre><code>Ваш код</code></pre>

Python | pack () в Tkinter

Python | pack () в Tkinter

Менеджер геометрии Pack упаковывает виджеты в строки или столбцы. Мы можем использовать такие параметры, как fill , expand и side для управления этим менеджером геометрии.
По сравнению с менеджером grid , менеджер pack несколько ограничен, но его намного проще использовать в нескольких, но довольно распространенных ситуациях:

  • Поместите виджет во фрейм (или любой другой виджет контейнера), и заполнив весь фрейм
  • Поместите несколько виджетов друг на друга
  • Поместите несколько виджетов рядом

Код # 1: Поместите виджет внутри фрейма и заполните весь фрейм.Мы можем сделать это с помощью опций expand и fill .

Python3

из tkinter import * из tkinter.ttk import *

master = Tk ()

панель = Фрейм (главный)

панель.упаковать (заполнить = ОБА, развернуть = True )

b1 = Кнопка (панель, текст = «Нажми меня!» )

b1.pack (заполнить = ОБА, развернуть = True )

b2 = Кнопка (панель, текст = "Нажмите я тоже » )

b2.pack (заполнить = ОБА, развернуть = True )

master.mainloop ()

Код выхода:

# 2: Размещение виджетов друг над другом и бок о бок. Мы можем сделать это побочным вариантом.

Python3

из tkinter импорт *

мастер = Tk ()

панель = = панель master)

панель.упаковать (заполнить = ОБА, развернуть = True )

b1 = Кнопка (панель, текст = «Нажми меня!» ,

фон = «красный» , fg = «белый» )

b1.pack (сторона = TOP, развернуть = True , заполнить = ОБА)

b2 = Кнопка (панель, текст = «Нажми и меня тоже» ,

фон = «синий» , fg = «белый» )

b2.pack (сторона = TOP, развернуть = True , заполнить = BOTH)

b3 = Кнопка (панель, текст = «Я тоже пуговица» ,

фон = «зеленый» , fg = «белый» )

b3.pack (сторона = TOP, развернуть = True , заполнить = BOTH)

master.mainloop ()

Выход:

Код # 3:

Python3

из tkinter импорт *

мастер =

Tk ()

панель = Фрейм (главный)

панель.упаковать (заполнить = ОБА, развернуть = True )

b1 = Кнопка (панель, текст = «Нажми меня!» ,

фон = «красный» , fg = «белый» )

b1.pack (сторона = LEFT, развернуть = True , заполнить = ОБА)

b2 = Кнопка (панель, текст = «Нажми меня тоже» ,

фон = «синий» , fg = «белый» )

b2.pack (сторона = LEFT, развернуть = True , заполнить = ОБА)

b3 = Кнопка (панель, текст = «Я тоже пуговица» ,

фон = «зеленый» , fg = «белый» )

b3.пакет (сторона = СЛЕВА, развернуть = True , заполнить = ОБА)

главный. главный контур ()

Выход:

Внимание компьютерщик! Укрепите свои основы с помощью курса Python Programming Foundation и изучите основы.

Для начала подготовьтесь к собеседованию. Расширьте свои концепции структур данных с помощью курса Python DS .И чтобы начать свое путешествие по машинному обучению, присоединяйтесь к Машинное обучение - курс базового уровня

Python struct pack, распакуйте - JournalDev

Структурный модуль Python способен выполнять преобразования между значениями Python и структурами C, которые представлены как строки Python.

Python Struct

  • Структурный модуль Python может использоваться для обработки двоичных данных, хранящихся в файлах, базе данных или из сетевых подключений и т. Д.
  • Он использует строки формата в качестве компактного описания макета структур C и предполагаемого преобразования в / из значений Python.

Функции Python Struct

В модуле struct есть пять важных функций: pack () , unpack () , calcsize () , pack_into () и unpack_from () . Во всех этих функциях мы должны указать формат данных, которые будут преобразованы в двоичные.

Вот некоторые из популярных символов формата:

 
?: логическое
h: короткий
l: длинный
я: int
f: плавать
q: длинный длинный int
  

Полный список символов формата можно посмотреть здесь.Давайте приступим к изучению функций модуля структуры одну за другой.

Python struct.pack ()

Эта функция упаковывает список значений в строковое представление указанного типа. Аргументы должны точно соответствовать значениям, требуемым форматом. Давайте быстро посмотрим на пример struct pack ():

 
структура импорта

var = struct.pack ('hhl', 5, 10, 15)
печать (var)
 
var = struct.pack ('iii', 10, 20, 30)
печать (var)
  

Когда мы запускаем этот сценарий, мы получаем следующее представление:

Обратите внимание, что «b» в Выходных данных означает двоичный.

Python struct.unpack ()

Эта функция распаковывает упакованное значение в его исходное представление в указанном формате. Эта функция всегда возвращает кортеж, даже если есть только один элемент. Давайте быстро посмотрим на пример функции struct unpack ():

 
структура импорта
var = struct.pack ('hhl', 5, 10, 15)
печать (var)
печать (struct.unpack ('hhl', var))
  

Когда мы запускаем этот скрипт, мы возвращаем свое исходное представление:

Очевидно, мы должны указать интерпретатору Python формат, в который нам нужно распаковать значения.

Python struct calcsize ()

Эта функция вычисляет и возвращает размер строкового представления структуры с заданным форматом.

Размер рассчитывается в байтах. Давайте быстро рассмотрим пример фрагмента кода:

 
структура импорта
 
var = struct.pack ('hhl', 5, 10, 15)
печать (var)
print ("Размер строкового представления равен {}.". format (struct.calcsize ('hhl')))
  

Когда мы запускаем этот скрипт, мы получаем следующее представление:

Python struct pack_into (), unpack_from ()

Эти функции позволяют нам упаковывать значения в строковый буфер и распаковывать из строкового буфера.Эти функции представлены в версии 2.5.

 
структура импорта
# ctypes импортируется для создания строкового буфера
import ctypes

# Как показано в предыдущем примере
размер = struct.calcsize ('hhl')
печать (размер)

# Буфер 'buff' создается из ctypes
buff = ctypes.create_string_buffer (размер)

# struct.pack_into () упаковывает данные в буфер и не возвращает никакого значения
# struct.unpack_from () распаковывает данные из баффа, возвращает кортеж значений
print (struct.pack_into ('hhl', бафф, 0, 5, 10, 15))
печать (struct.unpack_from ('hhl', бафф, 0))
  

Когда мы запускаем этот скрипт, мы получаем следующее представление:

Это все для краткого введения в модуль python struct .

Python struct pack, unpack - JournalDev

Модуль структуры Python может выполнять преобразования между значениями Python и структурами C, которые представлены как строки Python.

Python Struct

  • Структурный модуль Python может использоваться для обработки двоичных данных, хранящихся в файлах, базе данных или из сетевых подключений и т. Д.
  • Он использует строки формата в качестве компактного описания макета структур C и предполагаемого преобразования в / из значений Python.

Функции Python Struct

В модуле struct есть пять важных функций: pack () , unpack () , calcsize () , pack_into () и unpack_from () . Во всех этих функциях мы должны указать формат данных, которые будут преобразованы в двоичные.

Вот некоторые из популярных символов формата:

 
?: логическое
h: короткий
l: длинный
я: int
f: плавать
q: длинный длинный int
  

Полный список символов формата можно посмотреть здесь.Давайте приступим к изучению функций модуля структуры одну за другой.

Python struct.pack ()

Эта функция упаковывает список значений в строковое представление указанного типа. Аргументы должны точно соответствовать значениям, требуемым форматом. Давайте быстро посмотрим на пример struct pack ():

 
структура импорта

var = struct.pack ('hhl', 5, 10, 15)
печать (var)
 
var = struct.pack ('iii', 10, 20, 30)
печать (var)
  

Когда мы запускаем этот сценарий, мы получаем следующее представление:

Обратите внимание, что «b» в Выходных данных означает двоичный.

Python struct.unpack ()

Эта функция распаковывает упакованное значение в его исходное представление в указанном формате. Эта функция всегда возвращает кортеж, даже если есть только один элемент. Давайте быстро посмотрим на пример функции struct unpack ():

 
структура импорта
var = struct.pack ('hhl', 5, 10, 15)
печать (var)
печать (struct.unpack ('hhl', var))
  

Когда мы запускаем этот скрипт, мы возвращаем свое исходное представление:

Очевидно, мы должны указать интерпретатору Python формат, в который нам нужно распаковать значения.

Python struct calcsize ()

Эта функция вычисляет и возвращает размер строкового представления структуры с заданным форматом.

Размер рассчитывается в байтах. Давайте быстро рассмотрим пример фрагмента кода:

 
структура импорта
 
var = struct.pack ('hhl', 5, 10, 15)
печать (var)
print ("Размер строкового представления равен {}.". format (struct.calcsize ('hhl')))
  

Когда мы запускаем этот скрипт, мы получаем следующее представление:

Python struct pack_into (), unpack_from ()

Эти функции позволяют нам упаковывать значения в строковый буфер и распаковывать из строкового буфера.Эти функции представлены в версии 2.5.

 
структура импорта
# ctypes импортируется для создания строкового буфера
import ctypes

# Как показано в предыдущем примере
размер = struct.calcsize ('hhl')
печать (размер)

# Буфер 'buff' создается из ctypes
buff = ctypes.create_string_buffer (размер)

# struct.pack_into () упаковывает данные в буфер и не возвращает никакого значения
# struct.unpack_from () распаковывает данные из баффа, возвращает кортеж значений
print (struct.pack_into ('hhl', бафф, 0, 5, 10, 15))
печать (struct.unpack_from ('hhl', бафф, 0))
  

Когда мы запускаем этот скрипт, мы получаем следующее представление:

Это все для краткого введения в модуль python struct .

Python struct pack, unpack - JournalDev

Модуль структуры Python может выполнять преобразования между значениями Python и структурами C, которые представлены как строки Python.

Python Struct

  • Структурный модуль Python может использоваться для обработки двоичных данных, хранящихся в файлах, базе данных или из сетевых подключений и т. Д.
  • Он использует строки формата в качестве компактного описания макета структур C и предполагаемого преобразования в / из значений Python.

Функции Python Struct

В модуле struct есть пять важных функций: pack () , unpack () , calcsize () , pack_into () и unpack_from () . Во всех этих функциях мы должны указать формат данных, которые будут преобразованы в двоичные.

Вот некоторые из популярных символов формата:

 
?: логическое
h: короткий
l: длинный
я: int
f: плавать
q: длинный длинный int
  

Полный список символов формата можно посмотреть здесь.Давайте приступим к изучению функций модуля структуры одну за другой.

Python struct.pack ()

Эта функция упаковывает список значений в строковое представление указанного типа. Аргументы должны точно соответствовать значениям, требуемым форматом. Давайте быстро посмотрим на пример struct pack ():

 
структура импорта

var = struct.pack ('hhl', 5, 10, 15)
печать (var)
 
var = struct.pack ('iii', 10, 20, 30)
печать (var)
  

Когда мы запускаем этот сценарий, мы получаем следующее представление:

Обратите внимание, что «b» в Выходных данных означает двоичный.

Python struct.unpack ()

Эта функция распаковывает упакованное значение в его исходное представление в указанном формате. Эта функция всегда возвращает кортеж, даже если есть только один элемент. Давайте быстро посмотрим на пример функции struct unpack ():

 
структура импорта
var = struct.pack ('hhl', 5, 10, 15)
печать (var)
печать (struct.unpack ('hhl', var))
  

Когда мы запускаем этот скрипт, мы возвращаем свое исходное представление:

Очевидно, мы должны указать интерпретатору Python формат, в который нам нужно распаковать значения.

Python struct calcsize ()

Эта функция вычисляет и возвращает размер строкового представления структуры с заданным форматом.

Размер рассчитывается в байтах. Давайте быстро рассмотрим пример фрагмента кода:

 
структура импорта
 
var = struct.pack ('hhl', 5, 10, 15)
печать (var)
print ("Размер строкового представления равен {}.". format (struct.calcsize ('hhl')))
  

Когда мы запускаем этот скрипт, мы получаем следующее представление:

Python struct pack_into (), unpack_from ()

Эти функции позволяют нам упаковывать значения в строковый буфер и распаковывать из строкового буфера.Эти функции представлены в версии 2.5.

 
структура импорта
# ctypes импортируется для создания строкового буфера
import ctypes

# Как показано в предыдущем примере
размер = struct.calcsize ('hhl')
печать (размер)

# Буфер 'buff' создается из ctypes
buff = ctypes.create_string_buffer (размер)

# struct.pack_into () упаковывает данные в буфер и не возвращает никакого значения
# struct.unpack_from () распаковывает данные из баффа, возвращает кортеж значений
print (struct.pack_into ('hhl', бафф, 0, 5, 10, 15))
печать (struct.unpack_from ('hhl', бафф, 0))
  

Когда мы запускаем этот скрипт, мы получаем следующее представление:

Это все для краткого введения в модуль python struct .

Python struct pack, unpack - JournalDev

Модуль структуры Python может выполнять преобразования между значениями Python и структурами C, которые представлены как строки Python.

Python Struct

  • Структурный модуль Python может использоваться для обработки двоичных данных, хранящихся в файлах, базе данных или из сетевых подключений и т. Д.
  • Он использует строки формата в качестве компактного описания макета структур C и предполагаемого преобразования в / из значений Python.

Функции Python Struct

В модуле struct есть пять важных функций: pack () , unpack () , calcsize () , pack_into () и unpack_from () . Во всех этих функциях мы должны указать формат данных, которые будут преобразованы в двоичные.

Вот некоторые из популярных символов формата:

 
?: логическое
h: короткий
l: длинный
я: int
f: плавать
q: длинный длинный int
  

Полный список символов формата можно посмотреть здесь.Давайте приступим к изучению функций модуля структуры одну за другой.

Python struct.pack ()

Эта функция упаковывает список значений в строковое представление указанного типа. Аргументы должны точно соответствовать значениям, требуемым форматом. Давайте быстро посмотрим на пример struct pack ():

 
структура импорта

var = struct.pack ('hhl', 5, 10, 15)
печать (var)
 
var = struct.pack ('iii', 10, 20, 30)
печать (var)
  

Когда мы запускаем этот сценарий, мы получаем следующее представление:

Обратите внимание, что «b» в Выходных данных означает двоичный.

Python struct.unpack ()

Эта функция распаковывает упакованное значение в его исходное представление в указанном формате. Эта функция всегда возвращает кортеж, даже если есть только один элемент. Давайте быстро посмотрим на пример функции struct unpack ():

 
структура импорта
var = struct.pack ('hhl', 5, 10, 15)
печать (var)
печать (struct.unpack ('hhl', var))
  

Когда мы запускаем этот скрипт, мы возвращаем свое исходное представление:

Очевидно, мы должны указать интерпретатору Python формат, в который нам нужно распаковать значения.

Python struct calcsize ()

Эта функция вычисляет и возвращает размер строкового представления структуры с заданным форматом.

Размер рассчитывается в байтах. Давайте быстро рассмотрим пример фрагмента кода:

 
структура импорта
 
var = struct.pack ('hhl', 5, 10, 15)
печать (var)
print ("Размер строкового представления равен {}.". format (struct.calcsize ('hhl')))
  

Когда мы запускаем этот скрипт, мы получаем следующее представление:

Python struct pack_into (), unpack_from ()

Эти функции позволяют нам упаковывать значения в строковый буфер и распаковывать из строкового буфера.Эти функции представлены в версии 2.5.

 
структура импорта
# ctypes импортируется для создания строкового буфера
import ctypes

# Как показано в предыдущем примере
размер = struct.calcsize ('hhl')
печать (размер)

# Буфер 'buff' создается из ctypes
buff = ctypes.create_string_buffer (размер)

# struct.pack_into () упаковывает данные в буфер и не возвращает никакого значения
# struct.unpack_from () распаковывает данные из баффа, возвращает кортеж значений
print (struct.pack_into ('hhl', бафф, 0, 5, 10, 15))
печать (struct.unpack_from ('hhl', бафф, 0))
  

Когда мы запускаем этот скрипт, мы получаем следующее представление:

Это все для краткого введения в модуль python struct .

Узнайте, как использовать Pack в Tkinter

Tkinter - самый популярный пакет для разработки графических интерфейсов приложений Python. Tkinter предоставляет ряд виджетов, которые вы можете использовать для разработки своего графического интерфейса. Виджеты можно добавить в контейнер или фрейм, а затем запрограммировать для использования.

Tkinter имеет три менеджера компоновки, которые используют геометрические методы для размещения виджетов во фрейме приложения: упаковка, размещение, сетка.У каждого метода разные требования к кодированию. Обратите внимание, что если виджет добавлен во фрейм без использования диспетчера макетов, код может не выдать ошибку, но виджет не будет отображаться в кадре.

Менеджер компоновки пакетов

pack - это самый простой менеджер макетов для программирования в Tkinter.

Вместо объявления точного местоположения виджета, метод pack () объявляет положение виджетов относительно друг друга. Однако pack () имеет ограниченную точность по сравнению с place () и сеткой (), которые имеют абсолютное позиционирование. Для простого позиционирования виджетов по вертикали или горизонтали относительно друг друга pack () является предпочтительным менеджером компоновки.

pack () упорядочивает виджеты в горизонтальных и вертикальных полях, которые ограничены смещением влево, вправо, вверх, вниз и относительно друг друга в пределах кадра.

Пакет () Опции

Параметры pack (), описанные в этом разделе, реализованы в коде в следующих ниже примерах.

  • Сторона - это самый базовый вариант, включающий параметры заполнения для позиционирования виджетов по отношению к левой, правой, верхней, нижней сторонам виджета и относительно друг друга.
  • fill упаковывает виджет в контейнер, заполняя весь контейнер.
  • expand - это опция для назначения дополнительного места контейнеру виджета.

pack () также имеет варианты заполнения:

  • padx , который подкладывается снаружи по оси x.
  • pady , которые накладываются снаружи вдоль оси y.
  • ipadx , который размещается внутри по оси x.
  • ipady , который подкладывается внутри по оси y.

Pack () Синтаксис

  <имя_виджета>  .pack ( <параметры> )
 

Кнопка пакета Tkinter, пример 1

В этом примере к кнопке добавляется pack () без указания стороны.По умолчанию кнопка примыкает к верхней части рамки:

 из tkinter import *

корень = Tk ()
root.geometry ('200x150')
button1 = Кнопка (text = "Button1")
button1.pack ()

root.mainloop () 

Кнопка пакета Tkinter, пример 2

В этом примере pack () позиционирует четыре кнопки слева, справа, сверху и снизу от рамки. Из-за геометрии рамки и отсутствия прокладки кнопки могут казаться немного неравномерными по отношению друг к другу:

 из tkinter import *

корень = Tk ()
корень.геометрия ('250x150')

button1 = Кнопка (text = "Left")
button1.pack (сторона = ЛЕВАЯ)

button2 = Кнопка (text = "Top")
button2.pack (сторона = TOP)

button3 = Кнопка (текст = "Вправо")
button3.pack (сторона = ПРАВАЯ)
о
button4 = Кнопка (текст = "Внизу")
button4.pack (сторона = НИЖНИЙ)

root.mainloop () 

Кнопка пакета Tkinter, пример 3

В этом примере две кнопки расположены по отношению к нижней стороне рамки и друг от друга с использованием отступов:

 из tkinter import *

корень = Tk ()
корень.геометрия ('250x150')

button1 = Кнопка (text = "button1")
button1.pack (сторона = НИЖНИЙ, пады = 6)

button2 = Кнопка (text = "button2")
button2.pack (сторона = НИЖНИЙ, пады = 3)

root.mainloop ()
 

Пример заполнения пакета Tkinter

Параметр pack () fill используется для того, чтобы виджет заполнял весь фрейм . Параметр pack () expand используется для раскрытия виджета, если пользователь расширяет рамку.

заливка варианты:

  • НЕТ (по умолчанию), при котором будет сохранен исходный размер виджета.
  • X , заполнить по горизонтали.
  • Y , заполнить вертикально.
  • ОБА , заполнить по горизонтали и вертикали.

развернуть опции:

В этом примере список заполняет весь кадр. Если пользователь изменит размер фрейма, список расширится вместе с ним:

 из tkinter import *

корень = Tk ()

listbox = Список (корень)

# добавлена ​​опция заполнения, чтобы виджет заполнял весь фрейм.# Добавлена ​​опция раскрытия для расширения виджета, если пользователь изменяет размер кадра.
listbox.pack (fill = BOTH, expand = 1)

для z в диапазоне (  ):
listbox.insert (КОНЕЦ, стр (z))

mainloop () 

Tkinter Pack () Пример заполнения

pack () имеет опцию ipadx для внутреннего заполнения для управления виджетами по горизонтали и опцию ipady для управления виджетами по вертикали. Изменяется только внутренняя ширина и высота виджетов, позиционирование не изменяется.

В этом примере pack () включает параметры ipadx, ipady для управления шириной и высотой двух текстовых меток:

 импорт tkinter as tk

корень = tk.Tk ()
test = tk.Label (root, text = "Red", bg = "red", fg = "white")
test.pack (ipadx = 30, ipady = 6)
test = tk.Label (root, text = "Purple", bg = "purple", fg = "white")
test.pack (ipadx = 8, ipady = 12)
tk.mainloop () 

Понять, как работает диспетчер геометрии пакета Tkinter на примерах

Резюме : в этом руководстве вы узнаете о диспетчере геометрии Tkinter pack и его использовании для размещения виджетов в окне.

Введение в диспетчер геометрии пакетов Tkinter

До сих пор вы узнали, как использовать метод pack () для добавления виджетов в окно.

Чтобы расположить виджеты в окне, вы используете менеджеры геометрии. Метод pack () - один из трех менеджеров геометрии в Tkinter. Другие менеджеры геометрии - это сетка () и место () .

Диспетчер геометрии pack имеет множество конфигураций. Чаще всего используются следующие варианты: fill , expand , side , ipadx , ipady , padx и pady .

Давайте начнем с простой программы, чтобы лучше понять каждый вариант.

Пример диспетчера геометрии пакета Tkinter

Ниже показано, как использовать диспетчер геометрии пакета pack для размещения двух виджетов Label в корневом окне:

 

import tkinter as tk корень = tk.Tk () root.title ('Демо-версия') root.geometry ("300x200") box1 = tk.Label ( корень, text = "Коробка 1", bg = "зеленый", fg = "белый" ) box1.pack ( ipadx = 10, ipady = 10 ) box2 = tk.Этикетка( корень, text = "Box 2", bg = "красный", fg = "белый" ) box2.pack ( ipadx = 10, ipady = 10 ) root.mainloop ()

Язык кода: Python (python)

Вывод:

В этом примере для внутреннего заполнения используются ipadx и ipady . Эти параметры создают промежутки между метками и их границами.

Как видите, диспетчер геометрии pack размещает виджеты этикеток друг над другом.

1) Использование параметра заполнения

Параметр заполнения принимает три значения: 'x' , 'y' и 'оба' .Эти параметры позволяют виджету заполнять доступное пространство по оси X, оси Y и по обоим направлениям.

Если вы добавите fill = 'x' к первому виджету следующим образом:

 

box1.pack ( ipadx = 10, ipady = 10, fill = 'x' )

Язык кода: Python (python)

… вы увидите, что виджет заполняет все доступное пространство по оси x:

Однако, если вы измените значение на fill = 'y' следующим образом:

 

ящик 1.пакет( ipadx = 10, ipady = 10, fill = 'y' )

Язык кода: Python (python)

… вы увидите, что первый виджет не заполняет все пространство по вертикали:

В основном, диспетчер геометрии пакета выделяет пространство для каждого виджета, как показано ниже picture:

Когда вы используете опцию fill , область каждого виджета, которую можно заполнить, ограничивается этими выделенными областями.

Использование опции расширения

Опция expand выделяет больше доступного пространства для виджета.

Если вы добавите опцию expand к первому виджету:

 

box1.pack ( ipadx = 10, ipady = 10, expand = True )

Язык кода: Python (python)

… вы получите следующий результат:

Первый виджет занимает все доступное пространство в окне, за исключением пространства, выделенного второму виджету.

Поскольку первый виджет не имеет опции fill , он плавает в середине выделенной области.

Если вы установите заполните на 'оба' :

 

box1.pack ( ipadx = 10, ipady = 10, fill = 'оба', expand = True )

Язык кода: Python (python)

… вы увидите, что первый виджет заполняет большую часть окна следующим образом:

Если вы добавите опцию expand к обоим виджетам, менеджер пакета pack равномерно распределит им пространство. Например:

 

import tkinter as tk корень = тк.Тк () root.title ('Демо-версия') root.geometry ("300x200") box1 = tk.Label ( корень, text = "Коробка 1", bg = "зеленый", fg = "белый" ) box1.pack ( ipadx = 10, ipady = 10, expand = True, fill = 'оба' ) box2 = tk.Label ( корень, text = "Box 2", bg = "красный", fg = "белый" ) box2.pack ( ipadx = 10, ipady = 10, expand = True ) root.mainloop ()

Язык кода: Python (python)

Вывод:

Обратите внимание, что второй виджет не использует все выделенное пространство, потому что у него нет параметра fill .

Когда вы устанавливаете expand на True для всех виджетов, менеджер pack равномерно выделяет им пространство.

Однако это верно только тогда, когда все виджеты используют одну и ту же сторону привязки , .

Использование боковой опции

Сторона опция определяет выравнивание виджета. Это может быть «левый» , «верхний» , «правый» и «нижний» .

Сторона по умолчанию «верх» .Другими словами, виджеты выравниваются по верхнему краю своего контейнера.

В следующем примере для стороны первого виджета устанавливается значение «слева» :

 

import tkinter as tk корень = tk.Tk () root.title ('Демо-версия') root.geometry ("300x200") box1 = tk.Label ( корень, text = "Коробка 1", bg = "зеленый", fg = "белый" ) box1.pack ( ipadx = 10, ipady = 10, expand = True, fill = 'оба', сторона = 'слева' ) box2 = tk.Label ( корень, text = "Box 2", bg = "красный", fg = "белый" ) box2.пакет( ipadx = 10, ipady = 10, expand = True, fill = 'оба' ) root.mainloop ()

Язык кода: Python (python)

Вывод:

В этом примере опция expand может работать не так, как вы ожидали. Причина в том, что у виджетов разные стороны.

Чтобы сделать их пространство снова равномерным, вы можете установить сторону обоих виджетов на «левый» или один «левый» , а другой «правый» :

 

import tkinter as тк корень = тк.Тк () root.title ('Демо-версия') root.geometry ("300x200") box1 = tk.Label ( корень, text = "Коробка 1", bg = "зеленый", fg = "белый" ) box1.pack ( ipadx = 10, ipady = 10, expand = True, fill = 'оба', сторона = 'слева' ) box2 = tk.Label ( корень, text = "Box 2", bg = "красный", fg = "белый" ) box2.pack ( ipadx = 10, ipady = 10, expand = True, fill = 'оба', сторона = 'слева' ) root.mainloop ()

Язык кода: Python (python)

Вывод:

Когда использовать диспетчер геометрии упаковки

Диспетчер геометрии подходит для следующих целей:

  • Размещение виджетов в макете сверху вниз.
  • Размещение виджетов рядом

См. Следующий пример:

 

import tkinter as tk из tkinter import ttk корень = tk.Tk () root.title ('Демо-версия') root.geometry ("300x200") label1 = tk.Label ( корень, text = 'Поле 1', bg = "красный", fg = "белый" ) label1.pack ( ipadx = 10, ipady = 10, fill = 'x' ) label2 = tk.Label ( корень, text = 'Поле 2', bg = "зеленый", fg = "белый" ) label2.pack ( ipadx = 10, ipady = 10, fill = 'x' ) label3 = tk.Этикетка( корень, text = 'Поле 3', bg = "синий", fg = "белый" ) label3.pack ( ipadx = 10, ipady = 10, fill = 'x' ) label4 = tk.Label ( корень, text = 'Влево', bg = "голубой", fg = "черный" ) label4.pack ( ipadx = 10, ipady = 10, expand = True, fill = 'оба', сторона = 'слева' ) label5 = tk.Label ( корень, text = 'Центр', bg = "пурпурный", fg = "черный" ) label5.pack ( ipadx = 10, ipady = 10, expand = True, fill = 'оба', сторона = 'слева' ) label6 = tk.Label ( корень, text = 'Вправо', bg = "желтый", fg = "черный" ) этикетка6.пакет( ipadx = 10, ipady = 10, expand = True, fill = 'оба', сторона = 'слева' ) root.mainloop ()

Язык кода: Python (python)

Вывод:

Сводка