Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » Цикл по всем чекбоксам(100шт) в форме [RSS Feed]

#1 Март 13, 2013 15:16:21

Loki
Зарегистрирован: 2013-03-13
Сообщения: 28
Репутация: +  4  -
Профиль   Отправить e-mail  

Цикл по всем чекбоксам(100шт) в форме

Можно попробовать накапливать ссылки на чекбоксы в списке или в чем другом, а потом пустить цикл с eval() либо exec(). Недавно столкнулся с подобной проблемой, только вместо чекбоксов - LineEdit, причем их количество динамически меняется в зависимости от заполнения предыдущих форм и я пошел по описанному выше пути и все получилось.

Офлайн

#2 Март 13, 2013 15:26:45

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Цикл по всем чекбоксам(100шт) в форме

exec() - это последнее средство. Вечером выложу два скрипта и можно будет убедиться в этом :)



Офлайн

#3 Март 13, 2013 20:11:53

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Цикл по всем чекбоксам(100шт) в форме

Как и обещал. Первый пример. С использованием чекбоксов.

# -*- coding: utf-8 -*-
import Tkinter
# Создается главное окно
root = Tkinter.Tk()
root.geometry("400x400+100+100")
choise = [u"Первый показатель", u"Второй показатель", u"Третий показатель"]
variants = dict.fromkeys(choise, 0)
values = {}
# Функция для вывода общих результатов выбора
def print_all_choise(event):
    chek = event.widget
    variants[chek.cget("text")] = values[chek.winfo_id()].get()
    print repr(variants).decode("unicode_escape")
# Построение списка чекбоксов
for i in xrange(len(variants)):
    chek = Tkinter.Checkbutton(root, text=choise[i], font=14)
    chek.bind("<space>", print_state)
    chek.bind("<ButtonRelease-1>", print_state)
    chek.bindtags(("Checkbutton", chek))
    chek.grid(row=i, column=1, sticky="w")
    # Особое внимание на эту строку. Здесть определеяется
    # "ящичек" для хранения результатов каждого чекбокса
    # и формируется элементы словаря в котором по
    # уникальному имени виджета (ключу) хранится нужный
    # "ящичек" (значение).
    chek["variable"] = values[chek.winfo_id()] = Tkinter.IntVar()
root.mainloop()
Если что-то непонятно, можно спросить.

Но по правилу “7 плюс минус 2” количество чекбоксов не должно превышать 8 единиц (1 еденица на кнопку закрытия в ограничении “7 + 2”).

Следовательно, для случая необходимости выбора больше чем по 8 вариантам, этот способ не подходит.

Позже напишу как решить эту проблему с помощью двух списков (Listbox).



Отредактировано 4kpt (Март 13, 2013 22:03:27)

Офлайн

#4 Март 13, 2013 21:53:27

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Цикл по всем чекбоксам(100шт) в форме

Выкладываю второй вариант. Для настоящих мужчин :) С точки зрения дизайна пользовательского интерфейса - более правильный (и единственно возможный, если количество вариантов выбора больше 8 - я уже об этом писал).

# -*- coding: utf-8 -*-
import Tkinter
root = Tkinter.Tk()
root.geometry("500x200+100+100")
choise = [u"Первый показатель",
          u"Второй показатель",
          u"Третий показатель",
          u"Четвертый показатель"]
result = []
# Реакция на получение фокуса...
def focus_in(event):
    listbox_work = event.widget
    if listbox_work.size != 0:
        listbox_work.activate(0)
        listbox_work.selection_set(0)
def change_choise(event):
    # Выбор вариантов из всех возможных и запись их в список result
    # паралельно выбранные варианты удаляются из списка choise
    if event.widget.master.cget("text") == u"Все варианты" and choise:
        selection = int(event.widget.curselection()[0])
        result.append(choise[selection])
        Listbox_fr.delete(selection)
        Listbox_to.insert("end", choise.pop(selection))
        print repr(result).decode("unicode_escape")
    # Отказ от выбранных вариантом и удаление их из списка result
    # паралельно удаленные варианты добавляются в список choise
    elif event.widget.master.cget("text") == u"Выбранные варианты" and result:
        selection = int(event.widget.curselection()[0])
        choise.append(result[selection])
        Listbox_to.delete(selection)
        Listbox_fr.insert("end", result.pop(selection))
        print repr(result).decode("unicode_escape")
# Список всех вариантов на выбор
Frame_fr = Tkinter.LabelFrame(root, text=u"Все варианты", font=14)
Frame_fr.place(relx=0.25, rely=0.5, anchor="center")
Listbox_fr = Tkinter.Listbox(Frame_fr, width=20, height=4, font=14)
Listbox_fr.insert("end",*choise)
Listbox_fr.focus_force()
Listbox_fr.pack()
Listbox_fr.bind("<space>", change_choise)
Listbox_fr.bind("<FocusIn>", focus_in)
# Список выбранных вариантов
Frame_to = Tkinter.LabelFrame(root, text=u"Выбранные варианты", font=14)
Frame_to.place(relx=0.75, rely=0.5, anchor="center")
Listbox_to = Tkinter.Listbox(Frame_to, width=20, height=4, font=14)
Listbox_to.pack()
Listbox_to.bind("<space>", change_choise)
Listbox_to.bind("<FocusIn>", focus_in)
root.mainloop()
P.S. Скролы и все другие “няшечки” рекомендуется прилепить самостоятельно…



Отредактировано 4kpt (Март 13, 2013 22:04:15)

Офлайн

#5 Март 14, 2013 05:03:58

lotro
Зарегистрирован: 2012-10-03
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

Цикл по всем чекбоксам(100шт) в форме

Представляю Вам мое говнокодерство решение:

1. Создать кортеж такого вида(любое кол-во чекбоксов)

infec = (self.checkBox_4, self.checkBox_5, self.checkBox_6, self.checkBox_7, self.checkBox_8, self.checkBox_9, self.checkBox_10)

2. Проверять в цикле состояние чекбокса и сопоставлять со своим значением по словарю

for f in infec:
                        if f.isChecked():
                            str(checkB[f])

Оно даже работает



Офлайн

#6 Март 14, 2013 06:51:18

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Цикл по всем чекбоксам(100шт) в форме

infec = (self.checkBox_4, self.checkBox_5, self.checkBox_6, self.checkBox_7, self.checkBox_8, self.checkBox_9, self.checkBox_10)

infec = [ getattr(self, "checkBox_%s" x) for x in range(4,11) ]



Офлайн

#7 Март 26, 2013 21:57:11

KriO
Зарегистрирован: 2012-10-07
Сообщения: 61
Репутация: +  9  -
Профиль   Отправить e-mail  

Цикл по всем чекбоксам(100шт) в форме

А какой виджет является родителем у всех чекбоксов? QListWidget или просто Layout какой-то или ещё что? У Вас есть список или словарь этих чекбоксов?

Офлайн

#8 Март 27, 2013 01:20:25

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Цикл по всем чекбоксам(100шт) в форме

Какой QListWidget? Речь идет о Tkinter, а не о PyQt.



Офлайн

#9 Апрель 2, 2013 22:46:45

KriO
Зарегистрирован: 2012-10-07
Сообщения: 61
Репутация: +  9  -
Профиль   Отправить e-mail  

Цикл по всем чекбоксам(100шт) в форме

Топикстартер писал: “Оу. Извиняюсь. Я пишу c помощью PyQt 4.7
Лично для меня отдельный кайф вызывает рисование в Дизайнере.
Отредактировано lotro (Март 10, 2013 17:09:16)”

Так что изначально речь шла именно о PyQt.

Офлайн

#10 Апрель 3, 2013 00:57:44

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Цикл по всем чекбоксам(100шт) в форме

Да уже забыли о первом вопросе. Страницы полторы, как забыли :)



Офлайн

  • Начало
  • » GUI
  • » Цикл по всем чекбоксам(100шт) в форме[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version