Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » Определение выбранного пункта меню (Tkinter) [RSS Feed]

#1 Июнь 2, 2015 10:27:11

SirJorah
Зарегистрирован: 2015-04-21
Сообщения: 41
Репутация: +  2  -
Профиль   Отправить e-mail  

Определение выбранного пункта меню (Tkinter)

Уважаемые коллеги! Есть такой нехитрый код:

    def createMenu(self, master = None):
        self.mb = Menubutton(master, indicatoron = 1)
        self.mb.pack(padx = 2, pady = 1)
        self.menu = Menu(self.mb, tearoff = 0, bg = 'white')
        self.mb.configure(menu = self.menu)
        return self.mb
    def ConnectACAD(self):
        self.acad = GetActiveObject("AutoCAD.Application")
        self.dwg = self.acad.ActiveDocument
        self.mspace = self.dwg.ModelSpace
        self.master.title(self.title+' - '+self.dwg.Name.encode('utf-8'))
        for layer in self.dwg.Layers:
            self.menu.add_command(label = layer.Name, command = self.SetActiveLayer)
        self.mb.configure(text = self.menu.entrycget(0, 'label'))
        
    def SetActiveLayer(self):
        self.RefreshDisplay(self.menu.entrycget(ACTIVE, 'label'))
        
    def RefreshDisplay(self, layerString):
        self.mb.configure(text = layerString)
В данном случае меню в связке с Menubutton эмулирует отсутствующий в Tkinter ComboBox. Пункты меню именуются соответственно наименованиям слоев активного чертежа в AutoCAD. По освященной веками традиции ComboBox выбор пункта меню должен приводить к отображению наименования выбранного пункта на кнопке Menubutton (именно это пытается сделать процедура RefreshDisplay). Однако выбор любого пункта меню приводит к исчезновению надписи с Menubutton, т.е. entrycget возвращает пустую строку. Код обработчиков заимствован с данного весьма толкового ресурса: http://www.russianlutheran.org/python/nardo/nardo.html Вопрос: как правильно идентифицировать выбранный пункт меню? Заранее признателен за рекомендации.

Офлайн

#2 Июнь 2, 2015 11:26:32

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Определение выбранного пункта меню (Tkinter)

Очень просто. Использовать анонимную функцию lambda. Только не забудьте, что в цикле нужно объект слоя передавать явно.

Офлайн

#3 Июнь 2, 2015 15:09:05

SirJorah
Зарегистрирован: 2015-04-21
Сообщения: 41
Репутация: +  2  -
Профиль   Отправить e-mail  

Определение выбранного пункта меню (Tkinter)

Уважаемый друг! Огромное спасибо! Благодаря Вам изучил применение lambda в Tkinter. Вот так все работает:

    def ConnectACAD(self):
        self.acad = GetActiveObject("AutoCAD.Application")
        self.dwg = self.acad.ActiveDocument
        self.mspace = self.dwg.ModelSpace
        self.master.title(self.title+' - '+self.dwg.Name.encode('utf-8'))
        for x in xrange(0,self.dwg.Layers.Count) :
            self.menu.add_command(label = self.dwg.Layers[x].Name, command = lambda z = x: self.SetActiveLayer(z))
        self.MenuVar.set(self.menu.entrycget(0, 'label'))
        
    def SetActiveLayer(self, idx):
        self.MenuVar.set(self.menu.entrycget(idx, 'label'))

Отредактировано SirJorah (Июнь 2, 2015 15:09:34)

Офлайн

#4 Июнь 2, 2015 15:36:07

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Определение выбранного пункта меню (Tkinter)

Да пожалуйста.
Теперь минусы кода:
1. Не надо делать from tkinter import *
2. В свободное время почитайте про PEP8.
3. Почему:

command = lambda z = x: self.SetActiveLayer(z)

Так же логичнее

command=lambda x=x: self.SetActiveLayer(x)

P.S. Удачи в разработке. Сам долгое время проработал с Autocad…

Отредактировано 4kpt_III (Июнь 2, 2015 15:36:44)

Офлайн

#5 Июнь 2, 2015 15:59:59

SirJorah
Зарегистрирован: 2015-04-21
Сообщения: 41
Репутация: +  2  -
Профиль   Отправить e-mail  

Определение выбранного пункта меню (Tkinter)

Согласен. x=x тоже работает. И что не следует делать from tkinter import * - тоже поддерживаю. В действующем проекте (http://sourceforge.net/projects/xml2mif/) у меня так и написано:

from Tkinter import Tk, Button, Frame, Label, LabelFrame, Radiobutton, Entry, Text, Scrollbar, IntVar
from Tkinter import DISABLED, NORMAL, END
from tkFileDialog import Open, Directory
И про PEP8 почитаю. По Вашему совету - точно найду время. Еще раз благодарю.

Офлайн

#6 Июнь 2, 2015 16:03:14

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Определение выбранного пункта меню (Tkinter)

Да. Так действительно лучше, но…

from Tkinter import DISABLED, NORMAL, END

Гляньте, что там внутри

Офлайн

#7 Июнь 2, 2015 16:24:30

SirJorah
Зарегистрирован: 2015-04-21
Сообщения: 41
Репутация: +  2  -
Профиль   Отправить e-mail  

Определение выбранного пункта меню (Tkinter)

Хо-хо, глянуть еще не успел, но подозреваю, что как и в случае с упомянутой уважаемым Микки Нардо переменной (или скорее предполагается что константой) ACTIVE:
DISABLED = ‘disabled’
NORMAL = ‘normal’
END = ‘end’
))))
Кстати, если Вы долго работали с автокадом, может подкинете идейку, как обратиться к внутренней базе данных чертежа? db = dwg.Database срабатывает, а вот дальше - никакие StartTransaction не прокатывают. А лопатить чертеж с over 56K графических объектов, чтобы выбрать например все полилинии, принадлежащие определенному слою, по времени долго, тем более что ясно - можно быстрее, ведь команда QuickSelect конечно тоже немного думает, но в сравнении с полным перебором отвечает практически мгновенно.

Офлайн

#8 Июнь 2, 2015 16:27:18

4kpt_III
Зарегистрирован: 2014-12-22
Сообщения: 999
Репутация: +  39  -
Профиль   Отправить e-mail  

Определение выбранного пункта меню (Tkinter)

Работал как пользователь. Не в разрезе программирования

Офлайн

#9 Июнь 2, 2015 16:52:55

SirJorah
Зарегистрирован: 2015-04-21
Сообщения: 41
Репутация: +  2  -
Профиль   Отправить e-mail  

Определение выбранного пункта меню (Tkinter)

Ясно. Как пользователь я уж тоже давно тружусь. Программировать было пытался на Delphi, но из-за недостатка внятной документации бросил. Перешел на ГИС ObjectLand - там объектная модель в хелпе детально описана, поэтому не составляет труда внедрить окно карты в свою форму и тащить оттуда координаты полигонов (земельных участков), чтобы потом сформировать межевой план. Но сейчас работаю в конторе, где используют только автокад, поскольку съемку первоначально формируют топографы, потом с ней работают геологи, геофизики, гидрологи - и только в самом конце все это поступает в наш отдел, где мы должны разработать проект межевания земельных участков. Объекты тянутся на сотни километров, участков получаются тоже сотни, если не тысячи - и для каждого надо сформировать ведомость координат. Так что даже полным перебором объектов лучше, чем вручную. Выкину перебор объектов чертежа в отдельный поток, чтобы форма не “замерзала”, а тем временем продолжу искать подступы к database. Вот так как-то )))

Офлайн

#10 Июнь 2, 2015 17:57:43

Andrey Skobeldin
От: Saint-Petersburg
Зарегистрирован: 2011-01-25
Сообщения: 25
Репутация: +  1  -
Профиль   Отправить e-mail  

Определение выбранного пункта меню (Tkinter)

ИМХО, в Акаде, для выбора геометрических примитивов из какого либо пространства по определенным критериям лучше сформировать SelectionSet, а потом уже его проитерировать чтоли.



Офлайн

  • Начало
  • » GUI
  • » Определение выбранного пункта меню (Tkinter)[RSS Feed]

Board footer

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

Powered by DjangoBB

Lo-Fi Version