Slide 1

Slide 1 text

!1Z$PO+1 
 :VUB6SVTIJZBNB 1ZUIPOͰͭ͘Δએݴత6*ϥούʔϑϨʔϜϫʔΫ طଘ(6*ϑϨʔϜϫʔΫͷௐࠪΛఴ͑ͯ

Slide 2

Slide 2 text

࣫ࢁ༟ଠʢ:VUB6SVTIJZBNBʣ w ଔ ͱ͋Δ೶ۀͱձܭͷ*5اۀ w 1ZUIPOͱͷؔΘΓ ޱύΫಈը࡞੒πʔϧ 1Z1*ͰϥΠϒϥϦެ։ %4ࣾ಺ۀ຿γεςϜʢ0+5ʣ ࣾ಺ࢿ࢈ͷ"1*αʔόԽ ࣗݾ঺հ

Slide 3

Slide 3 text

1ZUIPOº(6*

Slide 4

Slide 4 text

ܦҢ ޱύΫಈը࡞੒πʔϧʹ(6*Λ͚͍ͭͨʂ w $-*͸࡞੒ࡁΈ $ python convert.py -i data/ -o target/ w πʔϧͷಛੑ্Ϛ΢ε͚ͩͰૢ࡞Ͱ͖ΔͱָͪΜ ϩδοΫ͸΋͏Ͱ͖ͯΔ͠ ָউͰ͠ΐ όΧ EBUB UFYU JNBHF WPJDF

Slide 5

Slide 5 text

ܦҢ ͋Εʁ1ZUIPOͰ(6*ͭ͘Δͷʢଞݴޠͱൺ΂ͯʣ໘౗͍͘͞ʁ w 5LJOUFS͸໋ྩత ίʔυ͔Βݟͨ໨Λ૝ىͮ͠Β͍ w 1Z4JNQMF(6*͸εοΩϦ͍ͯ͠Δ͚Ͳʜ 1ZUIPOͰ-(1-Wͳͷ͕νϣοτؾʹͳΔ w ,JWZ͸Ͳ͏ͯ͠ίʔυͱϏϡʔͷએݴ͕Θ͔ΕͯΔͷʁ

Slide 6

Slide 6 text

ܦҢ 3FBDU/BUJWFੈ୅?ͱͯ͠ͷෆຬ૑࡞ҙཉ 3FBDUΈ͍ͨͳએݴత6*ϑϨʔϜϫʔΫͳ͍͔ͳ͊ʙ ˝ 1ZUIPOͰ΋એݴత6*ϑϨʔϜϫʔΫͭ͘ΕΔͷ͔ͳʙ ˝ Α͠ɺ͍ͬͪΐ࡞ͬͯΈ·͔͢ʂ ?3FBDU͸೥ʹΦʔϓϯιʔεԽͨ͠ͷͰɺߴߍ࣌୅ʹϓϩάϥϛϯάʹڵຯΛ࣋ͬͨ୅͸(6*એݴత6*ͱ͍͏ࢥߟʹͳΓ΍͍͢ʁ

Slide 7

Slide 7 text

τϐοΫ w ͜Ε͔Β࿩͢͜ͱ 1ZUIPOͰ࢖͑Δ(6*ϑϨʔϜϫʔΫͷએݴత6*ࢹ఺Ͱͷ੔ཧ 1ZUIPOͰ3FBDUͷԾ૝%0.Λ໛฿ͨ͠࿩ w ࿩͞ͳ͍͜ͱ σʔλόΠϯσΟϯά ΠϕϯτϋϯυϦϯά

Slide 8

Slide 8 text

એݴత6*ͱ͸

Slide 9

Slide 9 text

ʮએݴత6*ʯͱ͸ʁ ྺ࢙తܦҢʛ໋ྩత6* w ೥୅·Ͱͷ(6*͸໋ྩత6*ϥΠϒϥϦ͕ओྲྀ Ͳͷ֊૚ɺͲͷҐஔʹ෦඼Λஔ͔͘ΛίʔυͰஞҰ੍ޚ ͳ͍͠ͷը໘ͷલͰΩʔϘʔυͱϚ΢εΛૢ࡞͢Δ 
 ۀ຿༻ύοέʔδιϑτΛ࡞Δͷʹ͸ద͍ͯͨ͠ ‣ 8'ͳΒը໘ઃܭ͸౓͖Γ ‣ ΢Πϯυ΢ॖখ΋αϙʔτ͢Δ࠷খղ૾౓·ͰͰ0,

Slide 10

Slide 10 text

w ೥୅·Ͱͷ(6*͸໋ྩత6*ϥΠϒϥϦ͕ओྲྀ Ͳͷ֊૚ɺͲͷҐஔʹ෦඼Λஔ͔͘ΛίʔυͰஞҰ੍ޚ ͳ͍͠ͷը໘ͷલͰΩʔϘʔυͱϚ΢εΛૢ࡞͢Δ 
 ۀ຿༻ύοέʔδιϑτΛ࡞Δͷʹ͸ద͍ͯͨ͠ ‣ 8'ͳΒը໘ઃܭ͸౓͖Γ ‣ ΢Πϯυ΢ॖখ΋αϙʔτ͢Δ࠷খղ૾౓·ͰͰ0, ྺ࢙తܦҢʛ໋ྩత6* ʮએݴత6*ϑϨʔϜϫʔΫʯͱ͸ʁ ͦΜͳ࣌୅͸΋͏աڈͷ΋ͷͰ͢ɻ ͦ͏ɺ˓1IPOFͳΒͶɻ

Slide 11

Slide 11 text

ʮએݴత6*ϑϨʔϜϫʔΫʯͱ͸ʁ ྺ࢙తܦҢʛ3FMFBTF&BSMZ 3FMFBTF0GUFO w ϞόΠϧ୺຤ͷը໘αΠζ͸ଟ༷Ͱ౷੍Ͱ͖ͳ͍ ը໘ઃܭͷݟ௚͠ස౓61 w ʮݸਓ͕࣋ͪӡ΂ΔΠϯλʔωοτʯͱͯ͠ͷڊେͰ৽͍͠Ϛʔέοτ εΫϥοϓˍϏϧυ΍ΞδϟΠϧ։ൃͷ૿Ճ ೲ඼ͱอक⾣ܧଓతͳΞοϓσʔτ

Slide 12

Slide 12 text

ʮએݴత6*ϑϨʔϜϫʔΫʯͱ͸ʁ ྺ࢙తܦҢʛ3FMFBTF&BSMZ 3FMFBTF0GUFO w ϞόΠϧ୺຤ͷը໘αΠζ͸ଟ༷Ͱ౷੍Ͱ͖ͳ͍ ը໘ઃܭͷݟ௚͠ස౓61 w ʮݸਓ͕࣋ͪӡ΂ΔΠϯλʔωοτʯͱͯ͠ͷڊେͰ৽͍͠Ϛʔέοτ εΫϥοϓˍϏϧυ΍ΞδϟΠϧ։ൃͷ૿Ճ ೲ඼ͱอक⾣ܧଓతͳΞοϓσʔτ ϥΠϑαΠΫϧ΍ঢ়ଶߋ৽ͷ࢓૊ΈΛࣗલͰ؅ཧͨ͘͠ͳ͍ 
 ˝ ϥΠϒϥϦ͔ΒϑϨʔϜϫʔΫ΁ ҟͳΔཁ݅Ͱมಈ͢Δ6*ͱঢ়ଶΛ෼ׂͯ͠؅ཧ͍ͨ͠ 
 ˝ ໋ྩత͔Βએݴతͳ6*΁

Slide 13

Slide 13 text

ʮએݴత6*ϑϨʔϜϫʔΫʯͱ͸ʁ ιϦϡʔγϣϯʛ6*ͱঢ়ଶΛ෼཭͠ɺڞ௨ͷ࢓ֻ͚Ͱ݁߹ͤ͞Δ w 6*ͱঢ়ଶͷ෼཭ Ծ૝%0.ʢৄࡉ͸ޙ΄Ͳʣ ‣ ࠓճ1ZUIPOͰ࣮૷ͨ͠෦෼ w 6*ͱঢ়ଶͷ݁߹ σʔλόΠϯσΟϯάʢ3FBDUJWF9΍1VC4VCͳͲʣ ‣ ༨ྗ͕ͳ࣮͘૷Ͱ͖͍ͯͳ͍😵💫

Slide 14

Slide 14 text

(6*ϑϨʔϜϫʔΫͷ੔ཧ

Slide 15

Slide 15 text

1ZUIPOͰ࢖͑Δ(6*ϑϨʔϜϫʔΫ ˞ϑϨʔϜϫʔΫϥΠϒϥϦͷ۠෼͸ͪ͝Ό·ͥ 1Z2U1Z4JEF ENAML FUD 'MFYY &EJ fi DF XY1ZUIPO ,JWZ

Slide 16

Slide 16 text

1ZUIPOͰ࢖͑Δ(6*ϑϨʔϜϫʔΫ ENAML 'MFYY &EJ fi DF FUD ໋ྩత6* XJUI2.- એݴత6* ෼཭ܕ ౷߹ܕ 1Z2U1Z4JEF XY1ZUIPO ,JWZ XJUILW

Slide 17

Slide 17 text

5LJOUFS एׯ͕ͤ͋͘Δ͕ࣗ༝౓ͷߴ͍ඪ४ϥΠϒϥϦ w ಺෦Ͱ5LͷίϚϯυΛݺͼग़͢ͷͰ 
 ඇৗʹखଓ͖త > pack .widget -side left w ͦͷͿΜॻ͖ํͷࣗ༝౓͕ߴ͍ w 5DM5Lͷ࣮ߦ؀ڥͷ४උ΍ 
 QZUIPO࣮ߦ؀ڥͱͷ૬ੑͳͲ 
 ͓खܰʹݟ͑ͯएׯ͓खܰͰͳ͍ ໋ྩత6* class HelloApp(tk.Frame): def __init__(self): self.master = tk.Tk() super().__init__(self.master, width=300, height=300) self.master.title("Hello Tkinter") # 双⽅向データバインディング self.m_text = tk.StringVar() # ラベル self.label = tk.Label( self, textvariable=self.m_text ).pack(side="top") # 1⾏テキストボックス self.textbox = tk.Entry( self, textvariable=self.m_text ).pack(side="left") # ボタン self.button = tk.Button( self, text="Clear", command=lambda: self.m_text.set("") ).pack(side="left") self.pack()

Slide 18

Slide 18 text

XY1ZUIPO 1IPFOJY 8JOEPXTϥΠΫʁͳ໋ྩత6*ϥΠϒϥϦ w 5LJOUFSʹࣅͨखଓ͖తهड़ w 8JOEPXTͷ(6*πʔϧΩοτʹ 
 ͍ۙจ๏Β͍͠ ݸਓతʹ͸ϝιου͕ 
 1BTDBM$BTFͳͷ͕޷ΈͰ͸ͳ͍ ࢲ͸🍎೿ͳͷͰΑ͘෼͔Γ·ͤΜ w ॻ͖ํΛؒҧ͑Δͱ༰қʹ 
 .&.03:@#"%@"$$&44ʹͳΔ ໋ྩత6* class HelloFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, 'Hello wxPython', size=(300, 300)) pnl = wx.Panel(self) # イベント駆動によるデータ更新 self.m_text = "" # ラベル self.st = wx.StaticText(pnl, label=self.m_text) # 1⾏テキストボックス self.tc = wx.TextCtrl(pnl) self.tc.Bind(wx.EVT_TEXT, self.on_type) # ボタン self.bt = wx.Button(pnl, wx.ID_CLEAR, label="Clear") self.bt.Bind(wx.EVT_BUTTON, self.on_clear) sizer = wx.GridBagSizer() sizer.Add(self.st, (0, 0), (1, 3), flag=wx.EXPAND) sizer.Add(self.tc, (1, 0), (1, 2), flag=wx.EXPAND) sizer.Add(self.bt, (1, 2), (1, 1), flag=wx.EXPAND) sizer.AddGrowableCol(1) pnl.SetSizer(sizer)

Slide 19

Slide 19 text

class HelloWidget(QWidget): def __init__(self): QWidget.__init__(self) # スロットによるイベント駆動 self.m_text = "" self.label = QLabel(self.m_text) self.label.alignment = Qt.AlignCenter self.text_entry = QLineEdit() self.text_entry.textChanged.connect(self.on_type) self.button = QPushButton("Clear") self.button.clicked.connect(self.on_clear) layout = QGridLayout() layout.add_widget(self.label, 0, 0) layout.add_widget(self.text_entry, 1, 0) layout.add_widget(self.button, 1, 1) self.set_layout(layout) @Slot() def on_type(self): self.label.text = self.text_entry.text @Slot() def on_clear(self): self.label.text = "" self.text_entry.text = "" w ڧྗͳ4JHOBM4MPU ΠϕϯτͷൃՐͱϩδοΫΛ 
 εϨουΛ௒͑ͯ෼཭Ͱ͖Δ w ΍΍͍͜͠બ୒ࢶͱϥΠηϯε 1Z2U 
 (1-W঎༻ 2UGPS1ZUIPO 
 (1-W-(1-W঎༻ 1Z2U2UGPS1ZUIPOʢچ1Z4JEFʣ ϥΠηϯεͷҟͳΔ2Uͷ1ZUIPOΠϯλϑΣʔε ໋ྩత6*

Slide 20

Slide 20 text

# --- QML --- import QtQuick import QtQuick.Controls import QtQuick.Layouts ApplicationWindow { title: qsTr("Hello QML") width: 300 height: 300 visible: true ColumnLayout { Text { id: text text: "" } RowLayout { Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom TextField { id: textfield text: "" Layout.alignment: Qt.AlignHCenter | Qt.AlignTop Layout.margins: 5 onTextChanged: { text.text = textfield.text } } Button { text: qsTr("Clear") onClicked: { text.text = "" w 2.-ͱ͍͏ϚʔΫΞοϓΛ༻͍ͯ 
 Ϗϡʔߏ଄Λએݴతʹهड़Ͱ͖Δ ؆୯ͳϩδοΫͳΒ2.-಺Ͱ 
 +BWB4DSJQUΛॻ͚ͯ͠·͏ 1Z2U1Z4JEFXJUI2.- 2UΛએݴతʹѻ͏ એݴత6*෼཭ܕ # --- Python --- if __name__ == "__main__": app = QApplication(sys.argv) engine = QQmlApplicationEngine() url = QUrl.fromLocalFile("view.qml") engine.load(url) if not engine.rootObjects(): sys.exit(-1) sys.exit(app.exec())

Slide 21

Slide 21 text

# --- 命令的UI --- from kivy.app import App from kivy.uix.button import Button class TestApp(App): def build(self): return Button(text='Hello World') TestApp().run() w ѻ͍΍͍͢.*5ϥΠηϯε w ΫϥεͱCVJMEϝιουͷ໭Γ஋Ͱ 
 ϏϡʔΛ૊ΈཱͯΔ ,JWZ ϞόΠϧʹ΋ରԠ͢ΔϑϨΩγϒϧͳϑϨʔϜϫʔΫ ໋ྩత6* IUUQTLJWZPSHIPNF

Slide 22

Slide 22 text

: label_wid: my_custom_label BoxLayout: orientation: 'vertical' padding: 20 Button: text: 'My controller info is: ' + root.info on_press: root.do_action() Label: id: my_custom_label text: 'My label before button press' w ϩδοΫ͸جຊతʹ1ZUIPOଆʹॻ͘ QSFTFOUBUJPOͱMPHJDͷ෼཭ w 6*ͱঢ়ଶ͸Ϋϥε໊Ͱ݁߹ ,JWZ,WMBOHVBHF ϞόΠϧʹ΋ରԠ͢ΔϑϨΩγϒϧͳϑϨʔϜϫʔΫ એݴత6*෼཭ܕ # --- 宣⾔的UI logic --- class Controller(FloatLayout): label_wid = ObjectProperty() info = StringProperty() def do_action(self): self.label_wid.text = 'My label after button press' self.info = 'New info text' class ControllerApp(App): def build(self): return Controller(info='Hello world') if __name__ == '__main__': ControllerApp().run() IUUQTLJWZPSHEPDTUBCMFHVJEFMBOHIUNMUIFMBZPVUHPFTJODPOUSPMMFSLW IUUQTLJWZPSHEPDTUBCMFHVJEFMBOHIUNMUIFDPEFHPFTJOQZ fi MFT

Slide 23

Slide 23 text

# person_view.enaml from enaml.widgets.api import ( Window, Form, Label, Field ) enamldef PersonView(Window): attr person title = 'Person View' Form: Label: text = 'First Name' Field: text := person.first_name Label: text = 'Last Name' Field: text := person.last_name w 1ZUIPOʹࣅͨߏจͰ6*Λهड़ ಈతʹ6*ͱঢ়ଶΛ݁߹Ͱ͖Δ w 1ZUIPOJDͳߏจͰ͋Δ͚ͩʹ 
 FOBNMϑΝΠϧͰͳ͘ 
 QZϑΝΠϧʹॻ͖ͨ͘ͳΔ &/".- 2Uͳ6*Λ1ZUIPOJDͳߏจͰهड़Ͱ͖ΔϑϨʔϜϫʔΫ એݴత6*෼཭ܕ IUUQTFOBNMSFBEUIFEPDTJPFOMBUFTUHFU@TUBSUFEBOBUPNZIUNMWJFX fi MFT

Slide 24

Slide 24 text

import edifice as ed from edifice import Label, TextInput, View class MyApp(ed.Component): def render(self): return View(layout="row")( Label("Measurement in meters:"), TextInput(""), Label("Measurement in feet:"), ) if __name__ == "__main__": ed.App(MyApp()).start() w 3FBDUΛ1ZUIPOʹϙʔτ͢Δͱ 
 ͜Μͳײ͡ɺΛ࣮ݱ͍ͯ͠Δ Ҿ਺ͱ໭Γ஋Ͱ໦ߏ଄Λܗ੒ w ࢠཁૉΛҾ਺Ͱ౉ͨ͢Ίɺ 
 ࢠཁૉͷมߋͷͨΊʹ͸ 
 ؔ਺νοΫͳ৚݅෼ذΛॻ͘ ಺แදه W JG D FMTF W &EJGJDF 2Uͳ6*Λ3FBDUͬΆ͘هड़Ͱ͖ΔϑϨʔϜϫʔΫ એݴత6*౷߹ܕ IUUQTXXXQZFEJ fi DFPSHUVUPSJBMIUNM

Slide 25

Slide 25 text

'MFYY 1ZUIPOίʔυ্Ͱ8FCϕʔεͷ6*Λهड़Ͱ͖ΔϑϨʔϜϫʔΫ એݴత6*౷߹ܕ w XJUIεςʔτϝϯτΛ׆༻ͨ͠ 
 ϏϡʔͷϏϧυ ࣗ࡞ޙʹطଘͷ΋ͷΛௐ΂ͨΒ 
 ΊͪΌͪ͘Όࣅ͍ͯͨ😅 w 8FCϕʔεͳͷͰಈ͔͢બ୒ࢶ͕ଟ͍ w 8FCϕʔεͳͷͰ 
 αʔόʢ1ZUIPOʣଆͱ 
 ΫϥΠΞϯτʢ+BWB4DSJQUʣଆΛ 
 ͦΕͧΕߟ͑Δඞཁ͋Γ from flexx import flx class Example(flx.Widget): def init(self): with flx.HSplit(): flx.Button(text='foo') with flx.VBox(): flx.Widget(style='background:red;', flex=1) flx.Widget(style='background:blue;', flex=1) if __name__ == "__main__": app = flx.App(Example) app.launch('app') flx.run() IUUQT fl FYYSFBEUIFEPDTJPFOTUBCMFHVJEFXJEHFU@CBTJDTIUNM IUUQT fl FYYSFBEUIFEPDTJPFOTUBCMFHVJEFSVOOJOHIUNM

Slide 26

Slide 26 text

Α͏΍͘ຊ୊

Slide 27

Slide 27 text

Slide 28

Slide 28 text

... with Body(clazz=["d-flex", ...]): with Header(clazz="mb-auto"): NavigationBar() # Component with Main(clazz=["container", ...]): with Division(clazz=["row", ...]): with Division(clazz=["col-sm-4"]): Image(clazz=["img-fluid"], src="/static/DeUI_logo.png") with Division(clazz=["col-sm-6"]): with Paragraph(clazz="h3"): Text(value="Declarative UI Wrapper Framework for Python") with Paragraph(): with Small(clazz="text-muted"): with Joined(): Text(value="The logo is inspired by ...") with Division(clazz=["row", "align-items-center"]): with Heading(level=1): Text(value="Register your account") with Paragraph(): Text(value="You have to make an account ...") Text(value="Please enter the form below ...") ...

Slide 29

Slide 29 text

1ZUIPOʹΑΔԾ૝%0.ͷ࣮૷

Slide 30

Slide 30 text

Ծ૝%0. ʮԾ૝ʯతͳʮ%PDVNFOU0CKFDU.PEFMʯ w ʮ%PDVNFOU0CKFDU.PEFMʯ λά෇͚͞ΕͨཁૉΛ໦ߏ଄ͰϞσϧԽ͢Δ͜ͱ͞Εͨ΋ͷ w ʮԾ૝ʯ ࣮ࡍͷ%0.ʢ㲈ը໘ʣͱ͸ಠཱ͍ͯ͠Δɺͱ͍͏ҙຯ ‣ 4PSUFE΍$PNQPOFOUͳͲͷ࿦ཧతཁૉΛؚΊΒΕΔ

Slide 31

Slide 31 text

ͳͥԾ૝%0.Λ༻͍Δ͔ "໰୊ͷ୯७Խͱಈ࡞ͷߴ଎Խ w Ծ૝%0.͸໦ߏ଄ %0.ͷૢ࡞ΛҰൠͷάϥϑཧ࿦ͱͯ͠ղऍͰ͖Δ ࠩ෼͚ͩΛݕग़Ͱ͖Ε͹ࠩ෼ͷ͋Δ࠷্ҐҎԼͷϊʔυ͚ͩߋ৽Ͱ͖Δ w Ծ૝%0.͸࣮ࡍͷ%0.ͱ͸ಠཱ ܰྔͳϊʔυ͚ͩΛ༻͍ͯ%0.Λಈతʹߋ৽Ͱ͖Δ

Slide 32

Slide 32 text

ͦΜͳ͜ͱݴΘΕͯ΋ 
 ࣮ࡍͲ͏࣮૷͢ΔΜͩʂ ໦ͷࠩ෼ݕग़͸ 0 O ͔͔Δͧʂ

Slide 33

Slide 33 text

େࣄͳ͜ͱ͸͢΂ͯ 
 3FBDU͕ڭ͑ͯ͘ΕΔ

Slide 34

Slide 34 text

3FBDUͷࠩ෼ݕग़ݪཧ IUUQTKBSFBDUKTPSHEPDTSFDPODJMJBUJPOIUNM w ΄΅ઢܗ࣌ؒͰۙࣅղΛٻΊΔ͜ͱ͕Ͱ͖Δ ਌ಉ͕࢜ҟͳΔཁૉͳΒͦΕҎ߱Λ͢΂ͯϦϏϧυ͢Δ ಉ͡ܕͷཁૉͳΒࠩ෼ͷଐੑͷΈΛߋ৽͢Δ ൺֱ͢ΔཁૉͷϖΞ͸ҰҙͳΩʔͰἧ͑Δ ͜ΕΛ1ZUIPOίʔυͰ࣮૷💪

Slide 35

Slide 35 text

ࠩ෼ݕग़ݪཧͷίʔυ ΍ͬͯΔ͜ͱ͸ඇৗʹγϯϓϧ w ϊʔυ͕ଘࡏ͠ͳ͍ͳΒ 
 ৽ͨʹ6*෦඼Λੜ੒͢Δ w ϊʔυ͕ଘࡏ͢ΔͳΒ 
 ੜ੒ࡁΈͷ6*෦඼Λड͚౉͢ w ϊʔυࣗ਎ͷঢ়ଶมԽ͸ 
 ϋογϡ஋ΛٻΊͯ௥੻ w ࠶ؼͰ౉͢ϊʔυରΛJEͰιʔτ @classmethod def update_tree(cls, old_t, new_t, root=Root): if new_t is None: return if (old_t is None or new_t.w_type is not old_t.w_type): # building new tree new_t.build(root=root) return # copy widget from old v-DOM-node to new one new_t.widget = old_t.widget new_t.widget.owner = weakref.ref(new_t) if new_t.hashcode != old_t.hashcode: # update widget parameters new_t.widget.update(*new_t.args, **new_t.kwargs) new_t.need_update = True # continue comparison order by id for old_st, new_st in align( old_t.children, new_t.children, key='id'): App.update_tree(old_st, new_st, root=root) IUUQTHJUIVCDPNVSVTIJZBNB%F6*CMPCEEBFEBEFFGFGCDEFVJDPSFBQQQZ--

Slide 36

Slide 36 text

NBHJD😎c🤯XJUI@@OFX@@

Slide 37

Slide 37 text

XJUIεςʔτϝϯτΛΫϥεͰ༻͍Δฐ֐ 8IBU*JOJUJBMJ[FJTOPUXIBUXFSFBMMZXBOUUPJOJUJBMJ[F w XJUIεςʔτϝϯτʹΫϥεͷ 
 ΦϒδΣΫτΛ౉͢ίʔυ 👍 BTʹΘͨ͢஋͸ 
 @@FOUFS@@Ͱࣗ༝ʹܾఆͰ͖Δ 👎 XJUIʹ౉࣌͢఺Ͱ 
 $POUFYUΫϥεͷ@@JOJU@@͕ 
 ૸ͬͯ͠·͏ class Context: def __init__(self): # some great initializations... pass def __enter__(self): # push context return some_obj # for `as` def __exit__(self, t, v, trace): # pop context pass ... # In use with Context() as context: pass

Slide 38

Slide 38 text

XJUIεςʔτϝϯτΛΫϥεͰ༻͍Δฐ֐ 8IBU*JOJUJBMJ[FJTOPUXIBUXFSFBMMZXBOUUPJOJUJBMJ[F XJUIʹ౉࣌͢఺ͰॳظԽ͍ͨ͠ͷ͸Ծ૝%0.ʢ7JFXʣ ÷ ϓϩάϥϚ͕XJUIʹ౉͍ͨ͠ͷ͸࣮ࡍͷ%0.ʢ8JEHFUʣ @@OFX@@ϝιουʹΑΔॳظԽ࣌ͷڍಈͷΦʔόʔϥΠυ

Slide 39

Slide 39 text

@@OFX@@ͱ͸ 1ZUIPOͷΠϯελϯεੜ੒🛵 w 1ZUIPO͸Πϯελϯεੜ੒࣌ʹͭͷϝιουΛݺͼग़͢ 1.__new__(cls, ...) ΫϥεͷΠϯελϯεੜ੒ͷͨΊʹݺ͹ΕΔ 2.__init__(self, ...) ΠϯελϯεͷॳظԽͷͨΊʹݺ͹ΕΔ ܕͷੈք ࣮ମͷੈք ⁞  

Slide 40

Slide 40 text

XJUI@@OFX@@ ΠϯελϯεԽͱίϯςΫετͷଋറͱͰΫϥεΛ෼཭ ࣮ࡍͷ%0.ʹରԠ͢Δ8JEHFUΛ 
 ΠϯελϯεԽ͠Α͏ͱ͢Δͱ 
 Ծ૝%0.ͷ7JFX͕ಉ࣌ʹ 
 ΠϯελϯεԽ͞Εɺ 8JEHFUͷΠϯελϯε͸ 
 ஗ԆධՁͰऔಘͰ͖Δ def __new__(cls, *args, **kwargs): view = View(cls, *args, **kwargs) widget = super().__new__(cls) widget.update(*args, **kwargs) def get_initial_widget(): widget.owner = weakref.ref(view) widget.update(*args, **kwargs) return widget view.get_initial_widget \ = get_initial_widget return view IUUQTHJUIVCDPNVSVTIJZBNB%F6*CMPCEEBFEBEFFGFGCDEFVJDPSFXJEHFUQZ--

Slide 41

Slide 41 text

@@OFX@@Λซ༻͢ΔϝϦοτ ΞεϖΫτࢦ޲ͳίϯςΫετଋറ w ίϯςΫετͷଋറΛܧঝͳ͠ʹผͷΫϥεʹҠৡͰ͖Δ 
 ΞεϖΫτࢦ޲ͳXJUIʹΑΔίϯςΫετଋറͷ࣮ݱ 8JEHFUΫϥεʹ͸@@FOUFS@@΍@@FYJU@@Λॻ͍͍ͯͳ͍ @@FOUFS@@ͱ@@FYJU@@Λϥοϓ͢Δ.BQQFSΛ༻ҙ͢Ε͹ 
 ෳ਺ͷίϯςΫετΛద༻Ͱ͖Δ ‣ IUUQTHJTUHJUIVCDPNVSVTIJZBNB DGFDBFECBECGEDD ʊਓਓਓਓਓਓਓਓਓʊ ʼɹଋറ͞Εͨ༨നɹʻ ʉ:?:?:?:?:?:?:?:ʉ

Slide 42

Slide 42 text

@@OFX@@Λ༻͍ΔσϝϦοτ ޫʁ͋Δͱ͜ΖʹӨ͋Γ w ҰൠతͳΠϯελϯεԽͱڍಈ͕ҟͳΔ όάϑΟοΫεͷ೉қ౓্ঢ w @@JOJU@@Λซ༻͢Δͱ͞ΒʹΧΦε ҆қʹ@@OFX@@಺ͰClass(…)Λݺͼग़͢ͱແݶϧʔϓʹؕΔ

Slide 43

Slide 43 text

࠷ޙʹ

Slide 44

Slide 44 text

࠷ޙʹ ͜Ε͔Βͷએݴత6*ͱϑϩϯτΤϯυ w એݴత6*͸σʔληοτʹର͢Δႈ౳ੑ͕͋ΔͨΊ 
 ҎԼͷٕज़ͱඇৗʹ૬ੑ͕ྑ͍ એݴܕϓϩάϥϛϯάݴޠʢ&MJYJS )BTLFMM ઌߦࣄྫతʹ͸&MNͳͲʣ ௚ྻԽՄೳͳߏ଄ମ ΞεϖΫτࢦ޲ͱ%*ʢઌߦࣄྫతʹ͸7VF$PNQPTJUJPO"1*ͳͲʣ એݴతͰঢ়ଶಉظ͠΍͍͢"1*ʢ(SBQI2-ͳͲʣ

Slide 45

Slide 45 text

࠷ޙʹ ͜Ε͔Βͷએݴత6*ͱϑϩϯτΤϯυͱ1ZUIPO w એݴత6*͸σʔληοτʹର͢Δႈ౳ੑ͕͋ΔͨΊ 
 ҎԼͷٕज़ͱඇৗʹ૬ੑ͕ྑ͍ એݴܕϓϩάϥϛϯάݴޠ ௚ྻԽՄೳͳߏ଄ମ ΞεϖΫτࢦ޲ͱ%* એݴతͰঢ়ଶಉظ͠΍͍͢"1* 👿Ҿ਺ͷείʔϓͰແ໊ؔ਺ΛఆٛͰ͖Ε͹ʜ 😇!EBUBDMBTT QZEBOUJD 😇UZQJOH1SPUPDPM NPOLFZQBUDI 😇๛෋ͳ(SBQI2-ϥΠϒϥϦ

Slide 46

Slide 46 text

࠷ޙʹ ͜Ε͔Βͷએݴత6*ͱϑϩϯτΤϯυͱ1ZUIPO w એݴత6*͸σʔληοτʹର͢Δႈ౳ੑ͕͋ΔͨΊ 
 ҎԼͷٕज़ͱඇৗʹ૬ੑ͕ྑ͍ એݴܕϓϩάϥϛϯάݴޠ ௚ྻԽՄೳͳߏ଄ମ ΞεϖΫτࢦ޲ͱ%* એݴతͰঢ়ଶಉظ͠΍͍͢"1* 👿Ҿ਺ͷείʔϓͰແ໊ؔ਺ΛఆٛͰ͖Ε͹ʜ 😇!EBUBDMBTT QZEBOUJD 😇UZQJOH1SPUPDPM NPOLFZQBUDI 😇๛෋ͳ(SBQI2-ϥΠϒϥϦ 👿😈👿😈👿1ZUIPOͰ൚༻తͳ(6*Λ૊Ήχʔζ

Slide 47

Slide 47 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

ิ଍ɿXJUIͷબఆཧ༝ w CVJMUJOͷTUBUFNFOU͕࢖͑Δ JGจ΍GPSจ͕࢖͑Δ 1ZUIPOͳΒ 
 NBUDI΋࢖͑Δ w ߏ଄͕ෳࡶԽͯ͠΋ 
 ؙׅހΛଟ༻ͤͣʹࡁΉ with NewsColumn(): for news_item in news_list: match news_item: case [title]: Bulletin(title) case [title, summary]: Headline(title, summary) case _: raise ValueError( "Unknown kind of news_item") จࣈྻҾ਺ͱ໭Γ஋Λ༻͍Δύλʔϯͱൺֱͨ͠ϝϦοτ

Slide 50

Slide 50 text

ิ଍ɿͳͥʮϥούʔʯʁ "ʮϥούʔʯʹ͠Α͏ͱ͍͔ͯͨ͠Β w Ծ૝%0.ʹج͍ͮͯ8JEHFUΛߋ৽͢ΔϥούʔίʔυΛॻ͚͹ 
 ཧ࿦্͸5LJOUFSͰ΋,JWZͰ΋ಉ༷ͷॻ͖ํͰϥοϓͰ͖Δ )5.-͸จࣈྻཁૉͷϥούʔ ,JWZͰ΋΍Ζ͏ͱ͍͕ͯͨ͠ 
 ʢຊۀָ͕͘͠๩͘͠ͳΓʣະணखͷ··

Slide 51

Slide 51 text

ิ଍ɿσʔλόΠϯσΟϯάͷల๬ (SBQI2-Λ༻͍ͨԾ૝εςʔτΛಋೖ͍ͨ͠