Найти - Пользователи
Полная версия: Listbox в Tkinter
Начало » GUI » Listbox в Tkinter
1 2 3 4 5 6
4kpt_II
AZJIO
Всмысле? Прикрутить ini-файл? Могу, только библиотеки ini что-то не увидел, могу через регулярные выражения сделать.

ConfigParser
AZJIO
4kpt_II
То что там есть даже для меня загадка. Есть примеры которые я сделал сам или переделал, а есть скопированные с сайтов. Может стоит открыть отдельную тему с названием “Архив примеров” и как то развивать это общими усилиями, с критикой и участием каждого. Потому что даже такое разделение 2.7.8 или 3.4, русифицировать или нет.
Yura_Lemeshko
AZJIO
Yura_LemeshkoВсмысле? Прикрутить ini-файл? Могу, только библиотеки ini что-то не увидел, могу через регулярные выражения сделать.

Если поможет в решении вопроса то пожалуйста сделайте.
AZJIO
Держи с сохранением.
1. Модуль для ini не стал использовать, так как проще сохранить списко как есть, текстом
2. Добавил ещё всякие проверки на ошибки, чтобы в консоль не писал
3. Добавил кнопку “Удалить”
4. Функции переместил на верх
5. Убрал все тестовые штучки

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# import sys
import tkinter as tk
import tkinter.filedialog as fdialog
# from tkinter import messagebox
from tkinter.messagebox import *
# ——————————————————————————————————————
# Функция чтения файла в Listbox
def read_file_to_lbox():
	try:
		f = open('lbox.txt', 'r') # Открывает файл для чтения
	except:
		# print("Could not open File: ")
		# print(sys.exc_info()[1])
		# Генерируем пункты для примера (вариант 1)
		# i=0
		# while 1:
			# i+=1
			# lbox1.insert(tk.END, 'Пункт ' + str(i))
			# if i == 40: break
		# 
		# Генерируем пункты для примера (вариант 2)
		list1=["Генеририруем","Тестовый","Если","не найден","файл","lbox.txt"] # Массив данных для вставки в Listbox
		for i in list1: # Цикл вставки в Listbox
			lbox1.insert(tk.END,i)
		return # Вылет, если не удалось открыть файл
	
	list1 = f.read() # Читает файл
	f.close() # Закрыть дескриптор файла
	list1 = list1.split('\n') # делит строку указаным разделителем, возвращая список
	for i in list1: # Цикл вставки в Listbox
		lbox1.insert(tk.END,i)
# ——————————————————————————————————————
# Функция связанная с кнопкой сохранения
def save_lbox_to_file():
	list1=lbox1.get(0, tk.END) # Получить все пункты списка
	string = ''
	for i in list1: # Соединяем в строку
		string += i + '\n'
	string = string.rstrip('\n') # справа обрезает все символы, указанные в перечислении
	sa = fdialog.asksaveasfilename(filetypes = [("Текстовые файлы", "*.txt")]) # вызов диалога сохранения
	try:
		f = open(sa, 'w') # Открыть файл, режим добавления
	except:
		# print("Could not open File: ")
		# print(sys.exc_info()[1])
		return # Вылет, если не удалось открыть файл
	f.write(string) # пишем строку пунктов в файл
	f.close() # Закрываем файл после записи
# ——————————————————————————————————————
# Функция связанная с выбором в Listbox
def lbox_item_to_entry(evt):
	inx = lbox1.index(tk.ANCHOR) # получаем индекс пункта
	if inx > lbox1.size() - 1: # Защита от применения действий к пункту без его выбора, список может быть пуст
		# print ('выберите пункт для начала')
		return
	value = lbox1.get(inx) # Получить выделенное
	edit1.delete(0, tk.END) # очищает поле ввода
	edit1.insert(0,value) # вставляет текст в поле ввода
# Устарела
# Функция связанная с выбором в Listbox
# def lbox_item_to_entry(evt):
	# value = lbox1.curselection()
	# if len(value) == 0: return # Если кортеж пустой, то вылет
	# value = value[0]
	# value = lbox1.get(value) # Получить выделенное
	# edit1.delete(0, tk.END) # очищает поле ввода
	# edit1.insert(0,value) # вставляет текст в поле ввода
# ——————————————————————————————————————
# Функция вставки
def lbox_added_item():
	text = str(edit1.get()) # Читаем поле ввода
	if not (text==''): # Проверяем что текст не пустой, перед вставкой
		lbox1.insert(tk.END,text) # Вставляет в конец списка
		edit1.delete(0, tk.END) # очищает поле ввода
		# lbox1.insert(3,'- "' + text + '" - вставлен в поз:3') # Вставляет в позицию 3
	else:
		showwarning('Предупреждение', 'Укажите текст добавляемого пункта')
# ——————————————————————————————————————
# Функция Редактирования
def lbox_edit_item():
	text = str(edit1.get()) # Читаем поле ввода
	if not (text==''): # Проверяем что текст не пустой, перед вставкой
		# print (text)
		# inx = lbox1.get(ACTIVE) # получаем текст пункта
		inx = lbox1.index(tk.ANCHOR) # получаем индекс пункта
		if inx > lbox1.size() - 1: # Защита от редактирования пункта без выбора
			showwarning('Предупреждение', 'Выберите пункт для редактирования')
			# print ('выберите пункт для начала')
			return
		lbox1.delete(inx) # удаляем пункт по индексу
		lbox1.insert(inx, text) # Вставляет пункт по индексу
		# lbox1.insert(inx, text + ' (удача ?)') # Для визуального теста
		edit1.delete(0, tk.END) # очищает поле ввода
	else:
		showwarning('Предупреждение', 'Укажите новый текст пункта')
# ——————————————————————————————————————
# Функция Редактирования
def lbox_delete_item():
	inx = lbox1.index(tk.ANCHOR) # получаем индекс пункта
	if inx > lbox1.size() - 1: # Защита от редактирования пункта без выбора
		showwarning('Предупреждение', 'Выберите пункт для удаления')
		return
	lbox1.delete(inx) # очищает поле ввода
# ——————————————————————————————————————
# Создаём GUI
root = tk.Tk() # Окно
root.geometry('200x380') # Размер окнаа
root.title('Окно оформления') # Заголовок окна
root.resizable(width = False, height = False) # Запрет на изменение размеров окна
label_1 = tk.Label(root, text = 'Список: ') # Создаём лейбл
label_1.place(x = 10, y = 10) # Задаём координаты лейбла
lbox1 = tk.Listbox(root) # Создаём список (, selectmode=MULTIPLE) (http://effbot.org/tkinterbook/listbox.htm)
lbox1.grid(padx=10, pady = 30) # Добавляем в слот grid с отступами
read_file_to_lbox()
edit1 = tk.Entry(root) # Создаём поле ввода
edit1.grid() # Добавляем в слот grid
# Связали (забиндили) событие выбора в Listbox с функцией "list_to_entry"
lbox1.bind('<<ListboxSelect>>', lbox_item_to_entry)
# Создаём фрейм для кнопок
frame_1 = tk.Frame(root, bg = '#bb9999', bd = 2) # Красноватый
frame_1.place(x = 30, y = 250 ) # Координаты размещения фрейма
# Создаём кнопки и вязываем с функциями
button_1 = tk.Button(frame_1, text = 'Добавить', command = lbox_added_item)
# button_1.place(x = 10, y = 230) # Не хотит в root прописываться кнопка и точка
# button_1.grid(row=1,column=1)
button_1.pack()
button_2 = tk.Button(frame_1, text = 'Удалить', command = lbox_delete_item)
button_2.pack()
button_3 = tk.Button(frame_1, text = 'Редактировать', command = lbox_edit_item)
button_3.pack()
button_4 = tk.Button(frame_1, text = 'Сохранить', command = save_lbox_to_file)
button_4.pack()
root.mainloop()

А так задаём кнопки без фрейма, в жёстких координатах, располагая в любом порядке.
# Создаём кнопки и вязываем с функциями
button_1 = tk.Button(root, text = '+', command = lbox_added_item)
button_1.pack()
button_1.place(x = 10, y = 250) # Если кнопку делаем в root, то координируем
button_2 = tk.Button(root, text = '-', command = lbox_delete_item)
button_2.pack()
button_2.place(x = 50, y = 250) # Если кнопку делаем в root, то координируем
button_3 = tk.Button(root, text = 'Правка', command = lbox_edit_item)
button_3.pack()
button_3.place(x = 90, y = 250) # Если кнопку делаем в root, то координируем
button_4 = tk.Button(root, text = 'Сохранить', command = save_lbox_to_file)
button_4.pack()
button_4.place(x = 30, y = 280) # Если кнопку делаем в root, то координируем
FishHook
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import tkinter as tk
import tkinter.filedialog as fdialog
from tkinter.messagebox import *
def read_file_to_lbox():
	try:
		f = open('lbox.txt', 'r') # Открывает файл для чтения
	except:
		list1=["Генеририруем","Тестовый","Если","не найден","файл","lbox.txt"] # Массив данных для вставки в Listbox
		for i in list1: # Цикл вставки в Listbox
			lbox1.insert(tk.END,i)
Но черт возьми, откуда же взялся lbox1?
Yura_Lemeshko
AZJIO
Держи с сохранением. 1. Модуль для ini не стал использовать, так как проще сохранить списко как есть, текстом2. Добавил ещё всякие проверки на ошибки, чтобы в консоль не писал3. Добавил кнопку “Удалить”4. Функции переместил на верх5. Убрал все тестовые штучки


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

AZJIO
Yura_Lemeshko
Так что ли? Так то у вас всё есть в скрипте, манипулируйте. А задачу лучше сразу оговаривать, чтобы по 100 раз не переписывать.
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# import sys
import tkinter as tk
import tkinter.filedialog as fdialog
# from tkinter import messagebox
from tkinter.messagebox import *
# ——————————————————————————————————————
# Функция чтения файла в Listbox
def read_file_to_lbox():
	try:
		f = open('lbox.txt', 'r') # Открывает файл для чтения
	except:
		# Генерируем пункты для примера (вариант 2)
		list1=["Генеририруем","Тестовый","Если","не найден","файл","lbox.txt"] # Массив данных для вставки в Listbox
		for i in list1: # Цикл вставки в Listbox
			lbox1.insert(tk.END,i)
		return # Вылет, если не удалось открыть файл
	
	list1 = f.read() # Читает файл
	f.close() # Закрыть дескриптор файла
	list1 = list1.split('\n') # делит строку указаным разделителем, возвращая список
	for i in list1: # Цикл вставки в Listbox
		lbox1.insert(tk.END,i)
# ——————————————————————————————————————
# Функция связанная с кнопкой сохранения
def save_lbox_to_file():
	list1=lbox1.get(0, tk.END) # Получить все пункты списка
	string = ''
	for i in list1: # Соединяем в строку
		string += i + '\n'
	string = string.rstrip('\n') # справа обрезает все символы, указанные в перечислении
	# sa = fdialog.asksaveasfilename(filetypes = [("Текстовые файлы", "*.txt")]) # вызов диалога сохранения
	try:
		f = open('lbox.txt', 'w') # Открывает файл для чтения
		# f = open(sa, 'w') # Открыть файл, режим добавления
	except:
		# print("Could not open File: ")
		# print(sys.exc_info()[1])
		return # Вылет, если не удалось открыть файл
	f.write(string) # пишем строку пунктов в файл
	f.close() # Закрываем файл после записи
	root.quit()
# ——————————————————————————————————————
# Функция связанная с выбором в Listbox
def lbox_item_to_entry(evt):
	inx = lbox1.index(tk.ANCHOR) # получаем индекс пункта
	if inx > lbox1.size() - 1: # Защита от применения действий к пункту без его выбора, список может быть пуст
		# print ('выберите пункт для начала')
		return
	value = lbox1.get(inx) # Получить выделенное
	edit1.delete(0, tk.END) # очищает поле ввода
	edit1.insert(0,value) # вставляет текст в поле ввода
# ——————————————————————————————————————
# Функция вставки
def lbox_added_item():
	text = str(edit1.get()) # Читаем поле ввода
	if not (text==''): # Проверяем что текст не пустой, перед вставкой
		lbox1.insert(tk.END,text) # Вставляет в конец списка
		edit1.delete(0, tk.END) # очищает поле ввода
		# lbox1.insert(3,'- "' + text + '" - вставлен в поз:3') # Вставляет в позицию 3
	else:
		showwarning('Предупреждение', 'Укажите текст добавляемого пункта')
# ——————————————————————————————————————
# Функция редактирования
def lbox_edit_item():
	text = str(edit1.get()) # Читаем поле ввода
	if not (text==''): # Проверяем что текст не пустой, перед вставкой
		# print (text)
		# inx = lbox1.get(ACTIVE) # получаем текст пункта
		inx = lbox1.index(tk.ANCHOR) # получаем индекс пункта
		if inx > lbox1.size() - 1: # Защита от редактирования пункта без выбора
			showwarning('Предупреждение', 'Выберите пункт для редактирования')
			# print ('выберите пункт для начала')
			return
		lbox1.delete(inx) # удаляем пункт по индексу
		lbox1.insert(inx, text) # Вставляет пункт по индексу
		# lbox1.insert(inx, text + ' (удача ?)') # Для визуального теста
		edit1.delete(0, tk.END) # очищает поле ввода
	else:
		showwarning('Предупреждение', 'Укажите новый текст пункта')
# ——————————————————————————————————————
# Функция удаления
def lbox_delete_item():
	inx = lbox1.index(tk.ANCHOR) # получаем индекс пункта
	if inx > lbox1.size() - 1: # Защита от редактирования пункта без выбора
		showwarning('Предупреждение', 'Выберите пункт для удаления')
		return
	lbox1.delete(inx) # удаляет пункт по индексу
# ——————————————————————————————————————
# Создаём GUI
root = tk.Tk() # Окно
root.geometry('190x320') # Размер окнаа
root.title('Окно оформления') # Заголовок окна
root.protocol('WM_DELETE_WINDOW', save_lbox_to_file) # обработчик закрытия окна
root.resizable(width = False, height = False) # Запрет на изменение размеров окна
label_1 = tk.Label(root, text = 'Список: ') # Создаём лейбл
label_1.place(x = 10, y = 10) # Задаём координаты лейбла
lbox1 = tk.Listbox(root) # Создаём список (, selectmode=MULTIPLE) (http://effbot.org/tkinterbook/listbox.htm)
lbox1.grid(padx=10, pady = 30) # Добавляем в слот grid с отступами
read_file_to_lbox()
edit1 = tk.Entry(root) # Создаём поле ввода
edit1.grid() # Добавляем в слот grid
# Связали (забиндили) событие выбора в Listbox с функцией "list_to_entry"
lbox1.bind('<<ListboxSelect>>', lbox_item_to_entry)
# Создаём кнопки и вязываем с функциями
button_1 = tk.Button(root, text = '+', command = lbox_added_item)
button_1.pack()
button_1.place(x = 10, y = 250) # Если кнопку делаем в root, то координируем
button_2 = tk.Button(root, text = '-', command = lbox_delete_item)
button_2.pack()
button_2.place(x = 50, y = 250) # Если кнопку делаем в root, то координируем
button_3 = tk.Button(root, text = 'Правка', command = lbox_edit_item)
button_3.pack()
button_3.place(x = 90, y = 250) # Если кнопку делаем в root, то координируем
button_4 = tk.Button(root, text = 'Сохранить и выйти', command = save_lbox_to_file)
button_4.pack()
button_4.place(x = 10, y = 280) # Если кнопку делаем в root, то координируем
root.mainloop()
4kpt_II
AZJIO
Еще раз. Почитайте про PEP8.
AZJIO
4kpt_II
Я прочитал, вчера или позавчера (сегодня у вас ссылка на англ. версию). Хорошая инструкция. Кстати а нет ли случайно инструмента для автоматического приведения кода к корректному виду? Типа Tidy.
4kpt_II
Приведения нет, но PyCharm версии выше 3 проверяет PEP8 автоматически и подчеркивает несоответствия еще при наборе кода. Кроме того, при наведении на подчеркивание, PyCharm отображает правило, в соответствии с которым обнаружена ошибка. Заодно он проверяет пересечение имен и еще много всего

Для PyScripter можно скачать и установить pylint. Он ставиться как расширение и позволяет анализировать код, но правда уже после написания. В этом случае в консоль PyScripter выводится трейсбек со всеми ошибками по оформлению и местами в коде, где возникли эти ошибки.

В чем работаете?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB