4クロックで支度しな

脊髄反射で思ったことを書き垂れます。68060とか名乗っときながら4クロックはヌルいとか言わないで。

Python3 + GTK+3をテストしてみる

概要

ちょっとしたGUIアプリケーションを作りたいと思い、MinGW上のPython3にpygobjectとGTK+3をインストールし、試しにコードを書いてみました。
GUIの部品配置はgladeで行い、CSSを適用しました。

ちなみに、MinGW上では、

pacman -S mingw-w64-x86_64-gtk3
pacman -S mingw-w64-x86_64-python3-gobject
pacman -S mingw-w64-x86_64-glade

にて必要なパッケージをインストールし、gladeはMSYS2のシェル上から起動します。

作ったものについて

とりあえず、CSSの適用と、ウィジェットの状態変化に応じて適用するCSSの変更を試してみたかったので、以下のようなものにしてみました。

  • テキストフィールド(Gtk.Entry)を3つ生成
  • 各テキストフィールドに対し、選択状態と非選択状態で異なるCSSを適用する

ソースコード

の3つです。

 import gi
 gi.require_version('Gtk', '3.0')
 from gi.repository import Gtk
 
 def entry_focus_in(entry, event):
     stylecontext = entry.get_style_context()
     stylecontext.add_class("borderentry")
     stylecontext.remove_class("noborderentry")
 
 def entry_focus_out(entry, event):
     stylecontext = entry.get_style_context()
     stylecontext.add_class("noborderentry")
     stylecontext.remove_class("borderentry")
 
 if __name__ == '__main__':
     builder = Gtk.Builder()
     builder.add_from_file("python_glade_test.glade")
     window = builder.get_object("mainframe")
     css_provider = Gtk.CssProvider()
     css_provider.load_from_path('style.css')
     Gtk.StyleContext.add_provider_for_screen(
         window.get_screen(),
         css_provider,
         Gtk.STYLE_PROVIDER_PRIORITY_USER)
 
     entry1 = builder.get_object("entry1")
     entry1.connect("focus-in-event", entry_focus_in)
     entry1.connect("focus-out-event", entry_focus_out)
     entry2 = builder.get_object("entry2")
     entry2.connect("focus-in-event", entry_focus_in)
     entry2.connect("focus-out-event", entry_focus_out)
     entry3 = builder.get_object("entry3")
     entry3.connect("focus-in-event", entry_focus_in)
     entry3.connect("focus-out-event", entry_focus_out)
     window.show_all()
     Gtk.main()
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- Generated with glade 3.20.2 -->
 <interface>
   <requires lib="gtk+" version="3.20"/>
   <object class="GtkWindow" id="mainframe">
     <property name="can_focus">False</property>
     <child>
       <object class="GtkBox">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
         <child>
           <object class="GtkEntry" id="entry1">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <style>
               <class name="borderentry"/>
             </style>
           </object>
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
             <property name="position">0</property>
           </packing>
         </child>
         <child>
            <object class="GtkEntry" id="entry2">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <style>
               <class name="noborderentry"/>
             </style>
           </object>
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
             <property name="position">1</property>
           </packing>
         </child>
         <child>
           <object class="GtkEntry" id="entry3">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <style>
               <class name="noborderentry"/>
             </style>
           </object>
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
             <property name="position">2</property>
           </packing>
         </child>
       </object>
     </child>
     <child type="titlebar">
       <placeholder/>
     </child>
   </object>
 </interface>
 .noborderentry {
 	font-family: "Meiryo", "Hiragino Kaku Gothic ProN", "MS PGothic", Osaka, sans-serif;
 }
 
 .borderentry {
 	font-family: "Meiryo", "Hiragino Kaku Gothic ProN", "MS PGothic", Osaka, sans-serif;
 	border-width: 2px;
 	border-color: #FF0000;
 	margin: 2px 2px 2px 2px;
 }

ちなみに、デフォルトでは何かひどいフォントで描画されるため、メイリオなどのフォントを明示的に指定しました。
上記3ファイルを同じフォルダに置き、

python3 python_glade_test.py

で実行します。
下記のような画面になるはずです。

f:id:Lil68060:20180122173922p:plain

ここで、3つのテキストフィールドをマウスで選択すると、選択したテキストフィールドへフォーカスが移ると共に、赤い枠線とマージンが移動することを確認できると思います。

追記

pygobject(pygi)とGTK+3で使用可能なCSSについて調べる際は、以下のサイトが役立つと思われます(正直かなり探し回りました)。