Питончик и Волшебные Картинки: Tkinter + Изображения и Выпадающие списки

Питончик и Волшебные Картинки

Tkinter + изображения, значки, выпадающие списки и смена картинок!

Новые волшебные заклинания Tkinter

Теперь Питончик научился:

  • Менять значок окна: window.wm_iconbitmap("icon.ico")
  • Менять цвет фона: window.configure(bg="light green")
  • Показывать картинки: PhotoImage(file="logo.gif")
  • Делать выпадающие списки: OptionMenu и StringVar
  • Менять картинку по нажатию!
# Важно: если хочешь менять картинку — сохрани ссылку!
photo = PhotoImage(file="bob.gif")
label["image"] = photo
label.image = photo # ← Вот эта строка — магия!

Задача 133

Создайте собственный значок для окна (в Paint нарисуйте разноцветные полоски, сохраните как MyIcon.ico).
Создайте логотип 200×150 (например, logo.gif).
Окно: поле ввода имени → кнопка "Press Me" → внизу появляется «Hello [имя]»

from tkinter import *

def greet():
    name = entry.get().strip()
    if name:
        result["text"] = f"Hello {name}!"
    else:
        result["text"] = "Привет, незнакомец!"

window = Tk()
window.title("Моё первое окно с логотипом!")
window.geometry("500x600")
window.wm_iconbitmap("MyIcon.ico")        # ← твой значок!
window.configure(bg="#E8F5E9")

# Логотип
logo = PhotoImage(file="logo.gif")
logo_label = Label(window, image=logo)
logo_label.image = logo
logo_label.pack(pady=20)

Label(text="Введи своё имя:", font=("Arial",16), bg="#E8F5E9").pack(pady=10)
entry = Entry(font=("Arial",18), width=20, justify="center")
entry.pack(pady=10)

Button(text="Press Me!", font=("Arial",16), command=greet, bg="#FF4081", fg="white").pack(pady=20)

result = Label(text="", font=("Arial",20,"bold"), bg="#E8F5E9", fg="#D500F9")
result.pack(pady=30)

window.mainloop()

Задача 134

Математическая игра: два случайных числа 10–50 → пользователь складывает.
Правильно → галочка (right.gif)
Неправильно → крестик (wrong.gif)
Кнопка «Next» — новый вопрос

from tkinter import *
import random

def new_question():
    global a, b, correct
    a = random.randint(10,50)
    b = random.randint(10,50)
    correct = a + b
    question["text"] = f"{a} + {b} = ?"
    entry.delete(0, END)
    result_label["image"] = ""  # убираем картинку

def check():
    try:
        answer = int(entry.get())
        if answer == correct:
            img = PhotoImage(file="right.gif")
            msg["text"] = "Молодец!"
        else:
            img = PhotoImage(file="wrong.gif")
            msg["text"] = f"Неправильно! Правильно: {correct}"
        result_label["image"] = img
        result_label.image = img
    except:
        msg["text"] = "Введи число!"

window = Tk()
window.title("Математическая викторина")
window.geometry("500x600")

question = Label(text="Нажми Next!", font=("Arial",24))
question.pack(pady=40)

entry = Entry(font=("Arial",20), width=10, justify="center")
entry.pack(pady=20)

Button(text="Проверить", command=check, font=18, bg="#4CAF50").pack(pady=10)
Button(text="Next", command=new_question, font=18, bg="#2196F3").pack(pady=10)

msg = Label(text="", font=("Arial",18))
msg.pack(pady=20)

result_label = Label()
result_label.pack(pady=30)

new_question()
window.mainloop()

Задача 135

Выпадающий список цветов → кнопка "Click Me" → фон окна меняется на выбранный цвет.
Без if! (используем словарь)

from tkinter import *

colors = {
    "Красный": "#FF5252",
    "Синий": "#448AFF",
    "Зелёный": "#66BB6A",
    "Жёлтый": "#FFEE58",
    "Фиолетовый": "#AB47BC",
    "Оранжевый": "#FF7043"
}

def change_color():
    color_name = var.get()
    window.configure(bg=colors[color_name])

window = Tk()
window.title("Волшебные цвета")
window.geometry("500x400")
window.configure(bg="#E0F7FA")

var = StringVar(window)
var.set("Красный")  # значение по умолчанию

option = OptionMenu(window, var, *colors.keys())
option.config(font=("Arial",18))
option.pack(pady=50)

Button(text="Click Me!", command=change_color, font=("Arial",20), bg="#FF4081").pack(pady=30)

Label(text="Выбери цвет и нажми кнопку!", font=("Arial",16), bg="#E0F7FA").pack()

window.mainloop()

Задача 136

Ввод имени + выбор пола (М/Ж) из выпадающего списка → кнопка → имя,пол добавляется в Listbox

from tkinter import *

def add_person():
    name = entry_name.get().strip()
    gender = var_gender.get()
    if name and gender != "Пол":
        listbox.insert(END, f"{name}, {gender}")
        entry_name.delete(0, END)

window = Tk()
window.title("Список людей")
window.geometry("500x600")

Label(text="Имя:").pack(pady=10)
entry_name = Entry(width=30, font=16)
entry_name.pack()

var_gender = StringVar(window)
var_gender.set("Пол")
OptionMenu(window, var_gender, "Пол", "М", "Ж").pack(pady=20)

Button(text="Добавить", command=add_person, font=16, bg="#4CAF50").pack(pady=10)

listbox = Listbox(width=50, height=20, font=14)
listbox.pack(pady=20)

window.mainloop()

Задача 137

Как 136 + всё сохраняется в файл people.txt
+ кнопка «Показать файл» — выводит содержимое в консоль

from tkinter import *

def add_and_save():
    name = entry_name.get().strip()
    gender = var.get()
    if name and gender != "Пол":
        record = f"{name}, {gender}\n"
        listbox.insert(END, record.strip())
        with open("people.txt", "a", encoding="utf-8") as f:
            f.write(record)
        entry_name.delete(0, END)

def show_file():
    try:
        with open("people.txt", "r", encoding="utf-8") as f:
            print("=== СОДЕРЖИМОЕ ФАЙЛА people.txt ===")
            print(f.read())
            print("===")
    except:
        print("Файл ещё пуст!")

window = Tk()
window.title("Сохранение в файл")
# ... (поля ввода как в 136)

Button(text="Добавить и сохранить", command=add_and_save).pack(pady=10)
Button(text="Показать файл в консоли", command=show_file, bg="#FF9800").pack(pady=10)

var = StringVar(window); var.set("Пол")
OptionMenu(window, var, "Пол", "М", "Ж").pack(pady=10)

listbox = Listbox(width=60, height=20); listbox.pack(pady=20)
window.mainloop()

Задача 138

В папке лежат картинки: 1.gif, 2.gif, 3.gif...
Пользователь вводит число → показывается соответствующая картинка

from tkinter import *

def show_image():
    num = entry.get().strip()
    if num.isdigit() and 1 <= int(num) <= 20:  # предполагаем до 20 картинок
        try:
            photo = PhotoImage(file=f"{num}.gif")
            image_label["image"] = photo
            image_label.image = photo  # сохраняем ссылку!
            status["text"] = f"Картинка {num}.gif загружена!"
        except:
            status["text"] = "Картинка не найдена!"
    else:
        status["text"] = "Введи число от 1 до 20!"

window = Tk()
window.title("Галерея по номеру")
window.geometry("700x700")

Label(text="Введи номер картинки (1-20):", font=18).pack(pady=30)
entry = Entry(font=20, width=10, justify="center")
entry.pack(pady=10)

Button(text="Показать!", command=show_image, font=20, bg="#9C27B0").pack(pady=20)

image_label = Label()
image_label.pack(expand=True)

status = Label(text="Жду номер...", font=16, fg="blue")
status.pack(pady=20)

window.mainloop()

Секретный код Волшебника Картинок

Только избранные знают его...

Ты стал настоящим Мастера Tkinter!
Теперь ты можешь создавать окна с картинками, значками и магией!
Питончик и Волшебная Книга Заклинаний: SQLite Базы Данных

Питончик и Волшебная Книга Заклинаний

Реляционные базы данных SQLite — магия хранения данных!

Что такое реляционная база данных?

Представь, что у тебя есть волшебный сундук с табличками, где каждая табличка — это таблица!

Вместо того чтобы повторять одно и то же (например, «отдел Sales» у десяти человек), мы выносим повторяющуюся информацию в отдельную табличку — и связываем их по ключу!

Это называется отношение «один ко многим»: один отдел — много сотрудников

import sqlite3
with sqlite3.connect("company.db") as db:
    cursor = db.cursor()

# Создаём таблицу
cursor.execute("""CREATE TABLE IF NOT EXISTS employees(
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    dept TEXT NOT NULL,
    salary INTEGER)""")

# Добавляем запись безопасно (с ?)
cursor.execute("INSERT INTO employees VALUES(?, ?, ?, ?)", (1, "Bob", "Sales", 25000))
db.commit()

Главное заклинание: ? — чтобы не поддаваться на проклятия SQL-инъекций!

Задача 139

Создать базу PhoneBook.db с таблицей Names и заполнить её 5 записями из телефонной книги.

import sqlite3

with sqlite3.connect("PhoneBook.db") as db:
    cursor = db.cursor()

    cursor.execute("""CREATE TABLE IF NOT EXISTS Names(
        ID INTEGER PRIMARY KEY,
        FirstName TEXT NOT NULL,
        Surname TEXT NOT NULL,
        PhoneNumber TEXT NOT NULL);""")

    data = [
        (1, "Simon", "Howeis", "01223 349752"),
        (2, "Karen", "Phillips", "01954 295773"),
        (3, "Darren", "Smith", "01583 749012"),
        (4, "Anne", "Jones", "01323 567322"),
        (5, "Mark", "Smith", "01223 855534")
    ]

    cursor.executemany("INSERT INTO Names VALUES(?, ?, ?, ?)", data)
    db.commit()

print("Телефонная книга создана!")

Задача 140

Полноценное меню для телефонной книги: просмотр, добавление, поиск по фамилии, удаление по ID, выход.

import sqlite3

def show_menu():
    print("\n=== ТЕЛЕФОННАЯ КНИГА ===")
    print("1. Просмотреть все записи")
    print("2. Добавить новую запись")
    print("3. Поиск по фамилии")
    print("4. Удалить по ID")
    print("5. Выйти")

def view_all(cursor):
    cursor.execute("SELECT * FROM Names")
    for row in cursor.fetchall():
        print(f"{row[0]}. {row[1]} {row[2]} — {row[3]}")

def add_record(cursor, db):
    fname = input("Имя: ")
    sname = input("Фамилия: ")
    phone = input("Телефон: ")
    cursor.execute("INSERT INTO Names(FirstName, Surname, PhoneNumber) VALUES(?, ?, ?)", (fname, sname, phone))
    db.commit()
    print("Запись добавлена!")

def search_surname(cursor):
    surname = input("Введите фамилию: ")
    cursor.execute("SELECT * FROM Names WHERE Surname=?", (surname,))
    results = cursor.fetchall()
    if results:
        for r in results:
            print(f"{r[1]} {r[2]} — {r[3]}")
    else:
        print("Ничего не найдено")

def delete_by_id(cursor, db):
    view_all(cursor)
    id_to_del = input("Введите ID для удаления: ")
    cursor.execute("DELETE FROM Names WHERE ID=?", (id_to_del,))
    db.commit()
    print("Запись удалена!")

with sqlite3.connect("PhoneBook.db") as db:
    cursor = db.cursor()

    while True:
        show_menu()
        choice = input("Выбор: ")
        if choice == "1": view_all(cursor)
        elif choice == "2": add_record(cursor, db)
        elif choice == "3": search_surname(cursor)
        elif choice == "4": delete_by_id(cursor, db)
        elif choice == "5": print("До свидания!"); break
        else: print("Неверный выбор!")

Задача 141

Создать базу BookInfo.db с двумя таблицами: Authors и Books (связь один-ко-многим).

import sqlite3

with sqlite3.connect("BookInfo.db") as db:
    cursor = db.cursor()

    cursor.execute("""CREATE TABLE IF NOT EXISTS Authors(
        Name TEXT PRIMARY KEY,
        PlaceOfBirth TEXT NOT NULL);""")

    cursor.execute("""CREATE TABLE IF NOT EXISTS Books(
        ID INTEGER PRIMARY KEY,
        Title TEXT NOT NULL,
        Author TEXT NOT NULL,
        DatePublished INTEGER NOT NULL,
        FOREIGN KEY(Author) REFERENCES Authors(Name));""")

    authors = [
        ("Agatha Christie", "Torquay"),
        ("Cecelia Ahern", "Dublin"),
        ("J. K. Rowling", "Bristol"),
        ("Oscar Wilde", "Dublin")
    ]

    books = [
        (1, "De Profundis", "Oscar Wilde", 1905),
        (2, "Harry Potter and the chamber of secrets", "J. K. Rowling", 1998),
        (3, "Harry Potter and the prisoner of Azkaban", "J. K. Rowling", 1999),
        (4, "Lyrebird", "Cecelia Ahern", 2017),
        (5, "Murder on the Orient Express", "Agatha Christie", 1934),
        # ... остальные книги
    ]

    cursor.executemany("INSERT INTO Authors VALUES(?, ?)", authors)
    cursor.executemany("INSERT INTO Books VALUES(?, ?, ?, ?)", books)
    db.commit()

print("База BookInfo создана!")

Задача 142

Ввести место рождения → вывести все книги авторов из этого места

place = input("Введите место рождения: ")
cursor.execute("""
    SELECT Books.Title, Books.DatePublished, Books.Author
    FROM Books JOIN Authors ON Books.Author = Authors.Name
    WHERE Authors.PlaceOfBirth = ?
    ORDER BY Books.DatePublished""", (place,))

for row in cursor.fetchall():
    print(f"{row[0]} ({row[1]}) — {row[2]}")

Задача 143

Ввести год → вывести все книги, изданные после него, по возрастанию года

year = int(input("Введите год: "))
cursor.execute("SELECT * FROM Books WHERE DatePublished > ? ORDER BY DatePublished", (year,))
for row in cursor.fetchall():
    print(f"{row[0]} - {row[1]} - {row[2]} - {row[3]}")

Задача 144

Ввести имя автора → сохранить все его книги в файл author_books.txt в формате: ID - Title - Author - Year

author = input("Введите имя автора: ")
cursor.execute("SELECT * FROM Books WHERE Author = ?", (author,))
books = cursor.fetchall()

with open("author_books.txt", "w", encoding="utf-8") as f:
    for book in books:
        f.write(f"{book[0]} - {book[1]} - {book[2]} - {book[3]}\n")

print(f"Книги автора {author} сохранены в author_books.txt!")

Задача 145

GUID-приложение: ввод имени и оценки → кнопка Add сохраняет в базу TestScores.db, Clear — очищает поля

from tkinter import *
import sqlite3

def add_score():
    name = entry_name.get().strip()
    score = entry_score.get().strip()
    if name and score.isdigit():
        with sqlite3.connect("TestScores.db") as db:
            c = db.cursor()
            c.execute("CREATE TABLE IF NOT EXISTS Scores(Name TEXT, Score INTEGER)")
            c.execute("INSERT INTO Scores VALUES(?, ?)", (name, int(score)))
            db.commit()
        status["text"] = f"Добавлено: {name} — {score}"
    else:
        status["text"] = "Проверь ввод!"

def clear():
    entry_name.delete(0, END)
    entry_score.delete(0, END)
    status["text"] = "Очищено!"

window = Tk()
window.title("Тестовые баллы")
window.geometry("500x600")

Label(text="Имя ученика:", font=20).pack(pady=20)
entry_name = Entry(font=20, width=20, justify="center")
entry_name.pack(pady=10)

Label(text="Балл:", font=20).pack(pady=10)
entry_score = Entry(font=20, width=10, justify="center")
entry_score.pack(pady=10)

Button(text="Add", command=add_score, font=20, bg="#00C853", fg="white").pack(pady=20)
Button(text="Clear", command=clear, font=20, bg="#FF5252", fg="white").pack(pady=10)

status = Label(text="Готов к вводу", font=18, fg="green")
status.pack(pady=30)

window.mainloop()

Секретное заклинание Великого Хранителя Данных

Тот, кто знает его — владеет всеми базами!

Ты стал Великим Хранителем Данных!
Теперь ты владеешь магией SQLite и реляционных баз!