어떻게 당신은 디자인에 매우"Pythonic"UI framework?
-
09-06-2019 - |
문제
제주도 루비 라이브러리"신발".기본적으로 작성할 수 있는 GUI 응용 프로그램에서 다음과 같은 방법으로:
Shoes.app do
t = para "Not clicked!"
button "The Label" do
alert "You clicked the button!" # when clicked, make an alert
t.replace "Clicked!" # ..and replace the label's text
end
end
이것은 나를 생각하게 될 것입니다 어떻게 디자인 마찬가지로 멋진 사용하 GUI 프레임워크에서는 파이썬?중 하나가 없는 일반적인 tyings 의 기본적으로는 래퍼 C*라이브러리(의 경우에는 프로그램,Tk,wx,QT 등)
신발 걸리는 것을 웹에서 개발되어(아 #f0c2f0
스타일 색상 표기법,CSS 레이아웃 기술처럼, :margin => 10
고),에서 루비(광범위하게 사용하여 블록에서 합리적인 방법)
Python 의 부족은"rubyish 블록을 만든다"는(은유적으로)-직접적인 포트가 불가능:
def Shoeless(Shoes.app):
self.t = para("Not clicked!")
def on_click_func(self):
alert("You clicked the button!")
self.t.replace("clicked!")
b = button("The label", click=self.on_click_func)
아무리 깨끗하고 있지 않을 것 거 으로 유연하고,나는지조차 확신이 들지 않습니다 그것은 것아야겠다.
를 사용하여 장식 것처럼 흥미로운 방법을 지도 블록의 코드의 특정 조치:
class BaseControl:
def __init__(self):
self.func = None
def clicked(self, func):
self.func = func
def __call__(self):
if self.func is not None:
self.func()
class Button(BaseControl):
pass
class Label(BaseControl):
pass
# The actual applications code (that the end-user would write)
class MyApp:
ok = Button()
la = Label()
@ok.clicked
def clickeryHappened():
print "OK Clicked!"
if __name__ == '__main__':
a = MyApp()
a.ok() # trigger the clicked action
기본적으로 장식 기능을 저장하는 함수,다음 작업이 발생한(예를 들어,클릭)해당 기능이 실행됩니다.
의 범위는 다양한 물건(말 la
레이블이 위의 예에서)가 될 수 있는 오히려 복잡,하지만 그것을 할 수 있는 것에서 상당히 깔끔한 방식으로..
해결책
당신으로부터 구제할 수 있습 이지만,그것은 필요한 것을 사용하여 메타클래스는 깊 매직(수 있 용).하려면 소개하는 메타클래스가 있는 시리즈의 기사에서 IBM 는 관리를 소개하는 아이디어를없이 녹는다.
소스 코드에서는 ORM 다음과 같 SQLObject 도움이 될 수 있기 때문에 그것은,너무,사용하는 이 같은 종류의 선언문입니다.
다른 팁
## All you need is this class:
class MainWindow(Window):
my_button = Button('Click Me')
my_paragraph = Text('This is the text you wish to place')
my_alert = AlertBox('What what what!!!')
@my_button.clicked
def my_button_clicked(self, button, event):
self.my_paragraph.text.append('And now you clicked on it, the button that is.')
@my_paragraph.text.changed
def my_paragraph_text_changed(self, text, event):
self.button.text = 'No more clicks!'
@my_button.text.changed
def my_button_text_changed(self, text, event):
self.my_alert.show()
## The Style class is automatically gnerated by the framework
## but you can override it by defining it in the class:
##
## class MainWindow(Window):
## class Style:
## my_blah = {'style-info': 'value'}
##
## or like you see below:
class Style:
my_button = {
'background-color': '#ccc',
'font-size': '14px'}
my_paragraph = {
'background-color': '#fff',
'color': '#000',
'font-size': '14px',
'border': '1px solid black',
'border-radius': '3px'}
MainWindow.Style = Style
## The layout class is automatically generated
## by the framework but you can override it by defining it
## in the class, same as the Style class above, or by
## defining it like this:
class MainLayout(Layout):
def __init__(self, style):
# It takes the custom or automatically generated style class upon instantiation
style.window.pack(HBox().pack(style.my_paragraph, style.my_button))
MainWindow.Layout = MainLayout
if __name__ == '__main__':
run(App(main=MainWindow))
그것은 상대적으로 쉽게 될 것이라 하에서는 파이썬의 비트와 함께하는 metaclass python 마법 방법을 알고 있습니다.는 난이 있습니다.고의 지식 PyGTK.는 또한다.아이디어를 얻?
내가 만족하지 않고 다윗 Mertz 의 기사에서 IBM metaclsses 그래서 최근에 쓴 내 자신 metaclass 문서.즐길 수 있습니다.
이것은 매우 고안하지 pythonic 에서 모든지만,여기에서의 내한 시도에 반 직역을 사용하여 새로운"와"문입니다.
with Shoes():
t = Para("Not clicked!")
with Button("The Label"):
Alert("You clicked the button!")
t.replace("Clicked!")
가장 어려운 부분을 다루는 사실과 함께하는 파이썬 제공하지 않습니다 우리에게 익명의 기능을 가진 하나 이상의 문습니다.의 주위에 얻을,우리는 우리의 목록을 만들 수 있습 명령어를 통해 실행하고 그...
어쨌든,여기에 코드 백엔드가 이:
context = None
class Nestable(object):
def __init__(self,caption=None):
self.caption = caption
self.things = []
global context
if context:
context.add(self)
def __enter__(self):
global context
self.parent = context
context = self
def __exit__(self, type, value, traceback):
global context
context = self.parent
def add(self,thing):
self.things.append(thing)
print "Adding a %s to %s" % (thing,self)
def __str__(self):
return "%s(%s)" % (self.__class__.__name__, self.caption)
class Shoes(Nestable):
pass
class Button(Nestable):
pass
class Alert(Nestable):
pass
class Para(Nestable):
def replace(self,caption):
Command(self,"replace",caption)
class Command(Nestable):
def __init__(self, target, command, caption):
self.command = command
self.target = target
Nestable.__init__(self,caption)
def __str__(self):
return "Command(%s text of %s with \"%s\")" % (self.command, self.target, self.caption)
def execute(self):
self.target.caption = self.caption
일부 Metaclass 마을 유지하는 순서 나는 다음과 같은 작업이다.나는 확실하지 않는 방법 pythonic 그것은 그러나 그것은 좋은 재미를 만들기 위한 간단한 일이다.
class w(Wndw):
title='Hello World'
class txt(Txt): # either a new class
text='Insert name here'
lbl=Lbl(text='Hello') # or an instance
class greet(Bbt):
text='Greet'
def click(self): #on_click method
self.frame.lbl.text='Hello %s.'%self.frame.txt.text
app=w()
다만 이렇게는 내가 알고 있는 Hans 노박의 왁스 (는 불행하게도 죽은 자).
가장 가까운 당신을 얻을 수 있습 rubyish 블록과 문서 pep343:
당신이 사용하는 경우 PyGTK 가 글레이드 고 이 glade 래퍼, 다음 PyGTK 실제로는 다소 pythonic.조금 적어도 있습니다.
기본적으로,당신은 만들 GUI 레이아웃에서 Glade.을 지정할 수도 있 이벤트 콜백에 glade.당신은 클래스를 작성한 창문에 다음과 같다:
class MyWindow(GladeWrapper):
GladeWrapper.__init__(self, "my_glade_file.xml", "mainWindow")
self.GtkWindow.show()
def button_click_event (self, *args):
self.button1.set_label("CLICKED")
여기에,나는 가정 하는 프로그램 버튼은 어딘가 불 button1 내가 지정 button_click_event 로 클릭 콜백입니다.Glade 래퍼는 데는 많은 노력을 밖의 이벤트 매핑을 사용합니다.
면 디자인 Pythonic GUI 라이브러리,나는 지원이 유사한 무언가 도움을 개발하기 시작했다.유일한 차이가 나는 것을 보장하는 위젯을 더 pythonic 인터페이스 너무입니다.현재 PyGTK 클래스 보 C 날을 제외하고,내가 사용하는 foo.bar(...)신의 바(foo,...)지 정확히 나는 무엇을 하는지 확인하십시오.아마도 허용 Django 모델 스타일을 선언하는 의미의 지정을 위젯과에 이벤트 코드고할 수 있도록 데이터에 액세스하지만 반복기(는 곳에 그것은,예를 들어,위젯 목록은 아마도),하지만 난 정말 그것에 대해 생각했다.
어쩌면하지 않으로 매끄러운 루비로 버전을,그러나는 방법에 대해 이 같은 것:
from Boots import App, Para, Button, alert
def Shoeless(App):
t = Para(text = 'Not Clicked')
b = Button(label = 'The label')
def on_b_clicked(self):
alert('You clicked the button!')
self.t.text = 'Clicked!'
같은 저스틴이 말, 을 구현하기 위해,이를 사용하는 것이 필요 사용자 지정 metaclass 에서 클래스 App
, 고 무리의 속성에 대 Para
고 Button
.이 실제로 없을 것이 너무 어렵습니다.
문제로 실행하는 다음은:당신은 어떻게 추적 주문 는 것을 표시되는 클래스 정의에?Python2.x,는 방법은 없을 경우 알 t
이상이어야 b
또는 다른 방법으로 주문을 받 클래스의 내용 정의로는 파이썬 dict
.
그러나,Python3.0 메타클래스에는 변경되는 에서 부부의(사소한)방식입니다.그 중 하나입니다 __prepare__
방법할 수 있는 공급하는 자신의 사용자 정의 사전 같은 객체에 사용되는 대신이 당신을 추적 할 수있는 순서 항목은 정의 위치는 그들을 따라 창에 표시됩니다.
이 될 수 있는 지나치게 단순,나는 생각하지 않는 것이 좋은 아이디어를 만들려고 일반적인 용도의 ui 라이브러리 이 방법입니다.다른 한편으로는 경우 이 방법을 사용할 수 있습(메타클래스고 친구)에 정의를 단순화의 특정 클래스의 사용자 인터페이스에 대한 기존 ui 라이브러리와 따라 응용 프로그램의할 수 있는 실제로 저장 당신이 상당한 양의 시간과 코드 라인입니다.
나는 이와 동일한 문제입니다.나는 완 래퍼를 만들어 주위에 어떤 GUI 툴킷에 대한 파이썬은 사용하기 쉬운,그리고 영감으로 신발,하지만 요구하 OOP 접근(에 대하여 루비 블록).
더 많은 정보: http://wiki.alcidesfonseca.com/blog/python-universal-gui-revisited
누군가의 참여를 환영합니다.
만약 당신이 정말로 원하는 코드 인터페이스를 가지고,당신을 시도할 수 있었을 얻을 비슷한 장고의 ORM;sth 다음과 같이 간단하는 데 도움 브라우저
class MyWindow(Window):
class VBox:
entry = Entry()
bigtext = TextView()
def on_entry_accepted(text):
bigtext.value = eval(text).__doc__
아이디어는 것을 해석하는 일부 콘테이너(windows)으로 간단한 수업,일부 컨테이너(테이블,v/hboxes)인하여 객체 이름,그리고 간단한 위젯으로 개체입니다.
나는 생각하지 말라 하나의 이름이 모든 용기 내부의 창,그래서 일부 바(올드 스타일의 클래스로 인식되는 위젯으로 이름)이 될 것이 바람직합니다.
의 순서에 대해 요소:에 MyWindow 위 없을 추적하이(창이 개념적으로는 하나의 슬롯 컨테이너).에서 다른 컨테이너 시도할 수 있습을 추적하기 위해 각 위젯을 생성자를 일부에 액세스할 수 있는 글로벌 위젯 목록입니다.이것은 어떻게 이에서 수행 django(AFAIK).
몇 해킹,여기에 몇 가지 바뀌는다.거기에 여전히 몇 가지의 생각,그러나 나는 그것이 가능하다 생각...하고 사용할 수 있는만큼 당신을 구축하지 않으면 복잡한 Ui.
그러나 나는 매우 행복 PyGTK+Glade.UI 은 종류의 데이터를 나를 위해야는 데이터로 처리됩니다.너무 많은 매개 변수를 조정(처럼 간격에서 다른 장소)하고 관리하는 GUI 를 사용하여 도구입니다.그러므로 내가 내 UI 에서 글레이드,저장 xml 및 분석을 사용하여 gtk.glade.XML().
선언은 반드시 이상(또는 이하)pythonic 보다는 기능적인 설계되었습니다.내가 생각하는 계층화된 접근 방식이 가장 좋은 것(에서 buttom 최대):
- 기본 레이어는 허용하고 반환하는 파이썬 데이터 유형이 있습니다.
- 기능적인 동적 계층입니다.
- 하나 이상의 선언/object-oriented 층이 있습니다.
비슷 Elixir + 정밀한 웹 애플리케이션을 빨리 빌.
개인적으로 난 것이 구현하십시오 JQuery 다음과 같 API 에서는 GUI framework.
class MyWindow(Window):
contents = (
para('Hello World!'),
button('Click Me', id='ok'),
para('Epilog'),
)
def __init__(self):
self['#ok'].click(self.message)
self['para'].hover(self.blend_in, self.blend_out)
def message(self):
print 'You clicked!'
def blend_in(self, object):
object.background = '#333333'
def blend_out(self, object):
object.background = 'WindowBackground'
여기에는 접근 방식에 대해 정의는 GUI 조금 다르게 사용하는 등 기반 메타-프로그래밍 보다는 오히려 상속입니다.
이 largley Django/의 정밀한 웹 애플리케이션을 빨리 빌서 영감을에서는 크게 기반으로 메타-프로그래밍 및 분리하의 GUI 코드에서"코드는"코드.또한 생각을 많이 사용하의 레이아웃 관리자는 다음과 같 Java 않기 때문에 당신이 떨어지는 코드,하지만 지속적으로 픽셀을 조정할 정렬.또한 것이라고 생각한다면 우리가 할 수 있 CSS 과 같은 속성이 있습니다.
여기에는 브레인스토밍을 거친 예를 보여줍니다 열 라벨에서 최고,다음 텍스트 상자를,다음 버튼을 클릭하시면 하단에 보여주는 메시지입니다.
from happygui.controls import * MAIN_WINDOW = Window(width="500px", height="350px", my_layout=ColumnLayout(padding="10px", my_label=Label(text="What's your name kiddo?", bold=True, align="center"), my_edit=EditBox(placeholder=""), my_btn=Button(text="CLICK ME!", on_click=Handler('module.file.btn_clicked')), ), ) MAIN_WINDOW.show() def btn_clicked(sender): # could easily be in a handlers.py file name = MAIN_WINDOW.my_layout.my_edit.text # same thing: name = sender.parent.my_edit.text # best practice, immune to structure change: MAIN_WINDOW.find('my_edit').text MessageBox("Your name is '%s'" % ()).show(modal=True)
하나 멋진 일을 알 수 있는 방법을 참조할 수 있습의 입력 my_edit 말 MAIN_WINDOW.my_layout.my_edit.text
.선언에 대한 창고 생각하는 것이 중요 할 수 있는 임의로 이름에서 컨트롤 기능 kwargs.
여기에는 같은 응용 프로그램만을 사용하여 절대 위치(컨트롤 다른 곳에서 나타날 때문에 우리가 사용하지 않는 멋진 레이아웃 관리자):
from happygui.controls import * MAIN_WINDOW = Window(width="500px", height="350px", my_label=Label(text="What's your name kiddo?", bold=True, align="center", x="10px", y="10px", width="300px", height="100px"), my_edit=EditBox(placeholder="", x="10px", y="110px", width="300px", height="100px"), my_btn=Button(text="CLICK ME!", on_click=Handler('module.file.btn_clicked'), x="10px", y="210px", width="300px", height="100px"), ) MAIN_WINDOW.show() def btn_clicked(sender): # could easily be in a handlers.py file name = MAIN_WINDOW.my_edit.text # same thing: name = sender.parent.my_edit.text # best practice, immune to structure change: MAIN_WINDOW.find('my_edit').text MessageBox("Your name is '%s'" % ()).show(modal=True)
나는 완전히 확실하지 않는 경우는 아직 이것은 매우 좋은 방법이지만,저는 확실히 생각하는 그의 오른쪽에서 경로.시간이 없어요 아이디어를 탐구해 더 많은,그러나 만약 누군가가 이 프로젝트로,나는 그들을 사랑합니다.