• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Статья Пишем графическую оболочку на Python - часть 3

Часть 1 Часть 2

Всем привет!

В предыдущих частях мы познакомились с двумя методами позиционирования элементов - pack() и place(). Для выполнения простых задач они вполне подходят. А если у нас планируется программа, где будет сложный интерфейс, или просто большое количество элементов, то самым лучшим методом будет несомненно grid(). На первый взгляд метод немного посложнее, но разобравшись в сути, он не станет выглядеть сложным.

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

tabl.jpg


То есть окно программы делится на столбцы и строки, а нумерация начинается с нуля. И прежде чем начать программировать, лучше всего начертить будущую программу на обычном листочке в клеточку. Это даст полное представление в какие ячейки что помещать. Столбцы и строки можно объединять с помощью columnspan и rowspan.

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

grid.png


Здесь у нас 4 кнопки для вычисления сложения, вычитания, умножения и деления, а также 2 однострочных текстовых поля для введения цифр. И в нижней части будут показываться результаты вычислений в многострочном текстовом поле. Как видно многострочное поле занимает по ширине 3 колонки, поэтому необходимо объединить колонки с помощью columnspan.

Согласно первой табличке, легко понять, что например кнопка minus- находиться в строке 0 и колонке 1. А теперь посмотрим код. Поскольку кнопки идут с левого верхнего угла, с них и нужно начинать.

Python:
plus_button = Button(text="plus +", width=14, command=plus)
plus_button.grid(row=0, column=0, padx=10, pady=5, sticky="n")

minus_button = Button(text="minus -", width=14, command=minus)
minus_button.grid(row=0, column=1, padx=10, pady=5, sticky="n")

multiply_button = Button(text="multiply *", width=14, command=multiply)
multiply_button.grid(row=1, column=0, padx=10, pady=5, sticky="n")

split_button = Button(text="divide /", width=14, command=split)
split_button.grid(row=1, column=1, padx=10, pady=5, sticky="n")

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

Python:
first_number = Entry(width=4, justify=CENTER)
first_number.grid(row=0, column=2, pady=5, sticky="ns")

two_number = Entry(width=4, justify=CENTER)
two_number.grid(row=1, column=2, pady=5, sticky="ns")

И завершает главное окно многострочное текстовое поле. Всё аналогично - размеры поля + позиционирование, и в данном случае объединение колонок.

Python:
text = Text(root, width=40, height=10)
text.grid(row=2, column=0, columnspan=3, padx=10, sticky='nswe')

Ну и чтобы всё это хозяйство заработало, нужно написать функции, которые будут делать вычисления при нажатии на соответствующие кнопки.

Python:
def plus():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a+b)
    text.insert(END, res + '\n')


def minus():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a - b)
    text.insert(END, res + '\n')


def multiply():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a * b)
    text.insert(END, res + '\n')


def split():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a / b)
    text.insert(END, res + '\n')

Обратите внимание, что поскольку математические действия мы производим с целыми числами, данные полученные от полей с цифрами, мы заворачиваем в int. А чтобы результаты вычислений были каждый раз с новой строки, мы добавили перенос строки '\n'. Но поскольку строки и числа не могут быть вместе при вставке вычислений в поле, то предварительно мы переводим результаты вычислений в строку с помощью str.

Python:
from tkinter import *

root = Tk()
root.title("Метод grid")
root.geometry("346x250")
root.resizable(width=False, height=False)


def plus():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a+b)
    text.insert(END, res + '\n')


def minus():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a - b)
    text.insert(END, res + '\n')


def multiply():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a * b)
    text.insert(END, res + '\n')


def split():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a / b)
    text.insert(END, res + '\n')


plus_button = Button(text="plus +", width=14, command=plus)
plus_button.grid(row=0, column=0, padx=10, pady=5, sticky="n")

minus_button = Button(text="minus -", width=14, command=minus)
minus_button.grid(row=0, column=1, padx=10, pady=5, sticky="n")

multiply_button = Button(text="multiply *", width=14, command=multiply)
multiply_button.grid(row=1, column=0, padx=10, pady=5, sticky="n")

split_button = Button(text="divide /", width=14, command=split)
split_button.grid(row=1, column=1, padx=10, pady=5, sticky="n")

first_number = Entry(width=4, justify=CENTER)
first_number.grid(row=0, column=2, pady=5, sticky="ns")

two_number = Entry(width=4, justify=CENTER)
two_number.grid(row=1, column=2, pady=5, sticky="ns")

text = Text(root, width=40, height=10)
text.grid(row=2, column=0, columnspan=3, padx=10, sticky='nswe')

root.mainloop()

Теперь проверим работоспособность программы. Запускаем и сделаем все вычисления по-очереди. Всё работает.

grid2.png


Вот и разобрались с методом grid(), как видите ничего сложного. Именно этот метод я и использую в большинстве случаев.
А теперь домашнее задание.

Продолжите работу с калькулятором, добавив 3 кнопки - exponentiation возведение в степень, rootin извлечение корня и Clean для очистки многострочного поля.

grid3.png


В данном примере я сначала ввёл 3 и 4, проделал вычисления, и чтобы проверить правильно ли у нас работает возведение в степень и извлечение корня, ввёл 81.
3 в 4 степени = 81 а извлечение из 81 корня 4 степени = 3 Всё верно.
 
M

Miron_T32

Часть 1 Часть 2

Всем привет!

В предыдущих частях мы познакомились с двумя методами позиционирования элементов - pack() и place(). Для выполнения простых задач они вполне подходят. А если у нас планируется программа, где будет сложный интерфейс, или просто большое количество элементов, то самым лучшим методом будет несомненно grid(). На первый взгляд метод немного посложнее, но разобравшись в сути, он не станет выглядеть сложным.

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

Посмотреть вложение 24944

То есть окно программы делится на столбцы и строки, а нумерация начинается с нуля. И прежде чем начать программировать, лучше всего начертить будущую программу на обычном листочке в клеточку. Это даст полное представление в какие ячейки что помещать. Столбцы и строки можно объединять с помощью columnspan и rowspan.

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

Посмотреть вложение 24945

Здесь у нас 4 кнопки для вычисления сложения, вычитания, умножения и деления, а также 2 однострочных текстовых поля для введения цифр. И в нижней части будут показываться результаты вычислений в многострочном текстовом поле. Как видно многострочное поле занимает по ширине 3 колонки, поэтому необходимо объединить колонки с помощью columnspan.

Согласно первой табличке, легко понять, что например кнопка minus- находиться в строке 0 и колонке 1. А теперь посмотрим код. Поскольку кнопки идут с левого верхнего угла, с них и нужно начинать.

Python:
plus_button = Button(text="plus +", width=14, command=plus)
plus_button.grid(row=0, column=0, padx=10, pady=5, sticky="n")

minus_button = Button(text="minus -", width=14, command=minus)
minus_button.grid(row=0, column=1, padx=10, pady=5, sticky="n")

multiply_button = Button(text="multiply *", width=14, command=multiply)
multiply_button.grid(row=1, column=0, padx=10, pady=5, sticky="n")

split_button = Button(text="divide /", width=14, command=split)
split_button.grid(row=1, column=1, padx=10, pady=5, sticky="n")

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

Python:
first_number = Entry(width=4, justify=CENTER)
first_number.grid(row=0, column=2, pady=5, sticky="ns")

two_number = Entry(width=4, justify=CENTER)
two_number.grid(row=1, column=2, pady=5, sticky="ns")

И завершает главное окно многострочное текстовое поле. Всё аналогично - размеры поля + позиционирование, и в данном случае объединение колонок.

Python:
text = Text(root, width=40, height=10)
text.grid(row=2, column=0, columnspan=3, padx=10, sticky='nswe')

Ну и чтобы всё это хозяйство заработало, нужно написать функции, которые будут делать вычисления при нажатии на соответствующие кнопки.

Python:
def plus():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a+b)
    text.insert(END, res + '\n')


def minus():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a - b)
    text.insert(END, res + '\n')


def multiply():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a * b)
    text.insert(END, res + '\n')


def split():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a / b)
    text.insert(END, res + '\n')

Обратите внимание, что поскольку математические действия мы производим с целыми числами, данные полученные от полей с цифрами, мы заворачиваем в int. А чтобы результаты вычислений были каждый раз с новой строки, мы добавили перенос строки '\n'. Но поскольку строки и числа не могут быть вместе при вставке вычислений в поле, то предварительно мы переводим результаты вычислений в строку с помощью str.

Python:
from tkinter import *

root = Tk()
root.title("Метод grid")
root.geometry("346x250")
root.resizable(width=False, height=False)


def plus():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a+b)
    text.insert(END, res + '\n')


def minus():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a - b)
    text.insert(END, res + '\n')


def multiply():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a * b)
    text.insert(END, res + '\n')


def split():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a / b)
    text.insert(END, res + '\n')


plus_button = Button(text="plus +", width=14, command=plus)
plus_button.grid(row=0, column=0, padx=10, pady=5, sticky="n")

minus_button = Button(text="minus -", width=14, command=minus)
minus_button.grid(row=0, column=1, padx=10, pady=5, sticky="n")

multiply_button = Button(text="multiply *", width=14, command=multiply)
multiply_button.grid(row=1, column=0, padx=10, pady=5, sticky="n")

split_button = Button(text="divide /", width=14, command=split)
split_button.grid(row=1, column=1, padx=10, pady=5, sticky="n")

first_number = Entry(width=4, justify=CENTER)
first_number.grid(row=0, column=2, pady=5, sticky="ns")

two_number = Entry(width=4, justify=CENTER)
two_number.grid(row=1, column=2, pady=5, sticky="ns")

text = Text(root, width=40, height=10)
text.grid(row=2, column=0, columnspan=3, padx=10, sticky='nswe')

root.mainloop()

Теперь проверим работоспособность программы. Запускаем и сделаем все вычисления по-очереди. Всё работает.

Посмотреть вложение 24946

Вот и разобрались с методом grid(), как видите ничего сложного. Именно этот метод я и использую в большинстве случаев.
А теперь домашнее задание.

Продолжите работу с калькулятором, добавив 3 кнопки - exponentiation возведение в степень, rootin извлечение корня и Clean для очистки многострочного поля.

Посмотреть вложение 24947

В данном примере я сначала ввёл 3 и 4, проделал вычисления, и чтобы проверить правильно ли у нас работает возведение в степень и извлечение корня, ввёл 81.
3 в 4 степени = 81 а извлечение из 81 корня 4 степени = 3 Всё верно.
Я бы хотел спросить насчёт двух текстовых полей sticky="ns". Почему ns? Ведь n - север, а s - юг. У кнопок только n, но при этом они расположены с текстовыми полями на одном уровне
 

explorer

Platinum
05.08.2018
1 081
2 474
BIT
14
Я бы хотел спросить насчёт двух текстовых полей sticky="ns". Почему ns? Ведь n - север, а s - юг. У кнопок только n, но при этом они расположены с текстовыми полями на одном уровне

Всё просто - если указать ns, то поле растягивается с севера на юг, таким образом кнопки и однострочные поля становятся одинакового размера. Просто сами попробуйте ставить разные значения, и сразу будет видна разница.

P.S. Надеюсь с этим вопросом разобрались. Дополню - в данном случае, кнопкам вообще не нужно указывать sticky, так как они занимают полностью весь размер ячейки. Но в одну ячейку не обязательно заключать один элемент. Их там может быть несколько. И вот тогда, чтобы они не накладывались друг на друга, необходимо использовать sticky и отступы.
 
Последнее редактирование:
  • Нравится
Реакции: Shadow User и dustver

explorer

Platinum
05.08.2018
1 081
2 474
BIT
14
Решение задачи

Python:
from tkinter import *

root = Tk()
root.title("Метод grid")
root.geometry("346x290")
root.resizable(width=False, height=False)


def plus():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a+b)
    text.insert(END, res + '\n')


def minus():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a - b)
    text.insert(END, res + '\n')


def multiply():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a * b)
    text.insert(END, res + '\n')


def split():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a / b)
    text.insert(END, res + '\n')


def exponentiation():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a ** b)
    text.insert(END, res + '\n')


def rooting():
    a = int(first_number.get())
    b = int(two_number.get())
    res = str(a**(1/b))
    text.insert(END, res + '\n')


def clean():
    text.delete(1.0, END)


plus_button = Button(text="plus +", width=14, command=plus)
plus_button.grid(row=0, column=0, padx=10, pady=5, sticky="n")

minus_button = Button(text="minus -", width=14, command=minus)
minus_button.grid(row=0, column=1, padx=10, pady=5, sticky="n")

multiply_button = Button(text="multiply *", width=14, command=multiply)
multiply_button.grid(row=1, column=0, padx=10, pady=5, sticky="n")

split_button = Button(text="divide /", width=14, command=split)
split_button.grid(row=1, column=1, padx=10, pady=5, sticky="n")

exponentiation_button = Button(text="exponentiation", width=14, command=exponentiation)
exponentiation_button.grid(row=2, column=0, padx=10, pady=5, sticky="n")

rooting_button = Button(text="rootin √", width=14, command=rooting)
rooting_button.grid(row=2, column=1, padx=10, pady=5, sticky="n")

clean_button = Button(text="Clean", width=6, command=clean)
clean_button.grid(row=2, column=2, pady=5, sticky="n")

first_number = Entry(width=4, justify=CENTER)
first_number.grid(row=0, column=2, pady=5, sticky="ns")

two_number = Entry(width=4, justify=CENTER)
two_number.grid(row=1, column=2, pady=5, sticky="ns")

text = Text(root, width=40, height=10)
text.grid(row=3, column=0, columnspan=3, padx=10, sticky='nswe')

root.mainloop()
 
  • Нравится
Реакции: BKeaton

Азиз

Green Team
30.05.2018
224
74
BIT
0
Графические оболочки программ напоминают мне html
 

explorer

Platinum
05.08.2018
1 081
2 474
BIT
14
Графические оболочки программ напоминают мне html

Есть некоторое сходство в атрибутах ширины, высоты, расположения и пр.
В следующей части поработаем над внешним видом программы, будем наводить красоту ;)
 
  • Нравится
Реакции: Shadow User и Азиз

win95

New member
04.03.2020
2
0
BIT
0
Спасибо, хороший цикл статей! А продолжение планируется?
 

explorer

Platinum
05.08.2018
1 081
2 474
BIT
14
Спасибо, хороший цикл статей! А продолжение планируется?

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

Devile_

Green Team
15.09.2020
26
20
BIT
0
Я пробовал сделать хотябы одну рабочую кнопку, пишет, что
command=plus
вот-тут команды plus не может быть.
Я уже даже перекопировал код с вашей статьи. Все равно пишет, что ее нет. Поможете разобраться?
 

explorer

Platinum
05.08.2018
1 081
2 474
BIT
14
Я пробовал сделать хотябы одну рабочую кнопку, пишет, что
command=plus
вот-тут команды plus не может быть.
Я уже даже перекопировал код с вашей статьи. Все равно пишет, что ее нет. Поможете разобраться?

Только что проверил, всё работает. Вы видимо по частям собирали и не весь код скопировали. Под спойлером код целиком, скопируйте оттуда.

212d.png
 

Devile_

Green Team
15.09.2020
26
20
BIT
0
Только что проверил, всё работает. Вы видимо по частям собирали и не весь код скопировали. Под спойлером код целиком, скопируйте оттуда.

Посмотреть вложение 43679
Я не копировал код, я писал его с помощью вашей статьи. Но во всем разобрался.. Там просто надо было функции кнопок поставить выше обозначений самих кнопок. Жду с нетерпением еще одну часть. А лучше еще три!!!
 

explorer

Platinum
05.08.2018
1 081
2 474
BIT
14
Написал ещё одну часть, но уже последнюю. На Tkinter можно тренироваться, это самая простая библиотека, для Windows вполне годный вариант, но с кроссплатформенным отображением есть проблемы.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!