2015年1月31日 星期六

pygtk圖片2疊到圖片1





google找到了,這裡是gnome文件說明

試了一下,把長頸鹿,疊到獅子,composite可帶透明度,scale則沒有(如下)



P2疊到P3
         Pixbuf.scale(P2,P3,0, 0, 50, 50, 0, 0, 1.0, 1.0, InterpType.BILINEAR)
P2疊到P
     Pixbuf.composite(P2, P1,0, 0, 50, 50, 0, 0, 1.0, 1.0, InterpType.BILINEAR, 127)



# main.py
# Copyright (C) 2015 yplin
#
# PIXBUF_IMAGE is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PIXBUF_IMAGE is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see .

from gi.repository import Gtk, GdkPixbuf, Gdk
import os, sys
from gi.repository.GdkPixbuf import Pixbuf, InterpType

#Comment the first line and uncomment the second before installing
#or making the tarball (alternatively, use project variables)
UI_FILE = "src/pixbuf_image.ui"
#UI_FILE = "/usr/local/share/pixbuf_image/ui/pixbuf_image.ui"


class GUI:
    def __init__(self):

        self.builder = Gtk.Builder()
        self.builder.add_from_file(UI_FILE)
        self.builder.connect_signals(self)
        self.image1=self.builder.get_object('image1')
        self.image2=self.builder.get_object('image2')
        self.image3=self.builder.get_object('image3')

        window = self.builder.get_object('window')
        P1= Pixbuf.new_from_file("src/logo.png")
        P2 = Pixbuf.new_from_file("src/p.jpeg")
        P3= Pixbuf.new_from_file("src/logo.png")
        Pixbuf.scale(P2,P3,0, 0, 50, 50, 0, 0, 1.0, 1.0, InterpType.BILINEAR)
        Pixbuf.composite(P2, P1,0, 0, 50, 50, 0, 0, 1.0, 1.0, InterpType.BILINEAR, 127)
        self.image1.set_from_pixbuf(P1)
        self.image2.set_from_pixbuf(P2)
        self.image3.set_from_pixbuf(P3)
        #Pixbuf.composite(P2, P1,0, 0, 50, 50, 0, 0, 1.0, 1.0, InterpType.BILINEAR, 127)
       


        window.show_all()

    def on_window_destroy(self, window):
        Gtk.main_quit()

def main():
    app = GUI()
    Gtk.main()
       
if __name__ == "__main__":
    sys.exit(main())


read more...

2015年1月29日 星期四

用python執行續來新增了播放圖片(download)

源碼下載(debian7.7,ubuntu1410測試OK,版本接近,或更新應該都OK)

畫面如下





我從ubuntu1410換到Debian7.7寫程式了,還是Debian穩定,而且文定多了


我在treeview_filechooser.py模組再新增一個MyThread執行續類別,處理播放圖片,開頭一定要加GObject.threads_init()

#此行一定要加,否則執行續,會停住
GObject.threads_init()    
#執行續,不能restart,只能重新產生,並等run執行完,會自動KILL
class MyThread(Thread):

.......................
.....................

若讓主程式用迴圈處理,其他事就不能做了,迴圈若放到執行續,就能同時進行
好比一個人就只能同時作一件事,多一個人就能再做一件事,執行續就像幫手

1.執行續,一旦啟動,就不能停止,只能等run()跑完,他會自動KILL
2.既然不能停止,只能讓他不做事,設個IF,然後由bollean控制它(如下)
   run()
       for ............:
         if(self.bollean)
           ...............

   def do_run(self,b):#決定是否工作
     self.bollean=b
3.執行續,不可能永遠存在run()跑完,他會自動KILL

  錯誤
  self.thread = MyThread(....)
  self.thread.start()
  ...........................
  #跑完,再啟動
  self.thread.start()

  正確
  self.thread = MyThread(....)
  self.thread.start()
  ...........................
  #跑完,再啟動
  self.thread = MyThread(....)
  self.thread.start()

程式邏輯,當按下播放紐,啟動執行續,讓他取得開始播放位置,並計算列表長度,for逐一選中列表,
列表選中cursor-changed信號被觸發,信號連到調整圖片大小,中途想停止播放,設個IF來判斷(run如下)

    def run(self):#執行續self.thread.start()執行的地方
      
        try:
        #while not self.stopped.wait(self.t):
            #判斷播放完,self.player_number應設成0,在重播
            if(self.player_number+1>=self.len):self.player_number=0
            print("my thread start")
            for x in range(self.player_number,self.len):
             #因為thread一起動,便不能中止,指能讓run不做任何事,走完自動KILL
             if(self.is_PLAY):
                  try:
                   #設定treeview選中項目,因為cursor-changed所以會發出信號,調整圖片
                   #Gdk.threads_enter()
                   #GObject.idle_add(self.tt.set_cursor(x))
                   self.tt.set_cursor(x)
                   #Gdk.threads_leave()
                   time.sleep(self.t)
                  except:self.stop()
             #self.stopped.wait(1)
            print("my thread stop")
        except:pass
    #讓執行續,快速結束
    def stop(self):
        self.stopped.set()
        self.is_PLAY=False
      
    #設定True或False,決定是否resize image
    def set_PLAY(self,boolean):
        self.is_PLAY=boolean
    #設定播放號碼
    def set_play_number(self,i):
        self.player_number=i




def set_PLAY(self,boolean)設定是否設定列表,當使用者按停止self.is_PLAY為False,播放停止
def set_play_number(self,i)當使用者未按播放紐,選中列表,告訴run播放位置
def stop(self)讓執行續,快速結束,跟set_PLAY(False)一樣,多了self.stopped.set(),會更快結束

另外,ui檔用glade多了scale元件,scale放入調整的adjustment1,來控制速度,get_value()可取得調整值


read more...

2015年1月27日 星期二

pygtk圖片檢視器完成了(程式下載)

算是有點水準的圖片檢視器(原碼下載)

下面是在ubuntu1410執行後樣子,OS版本不要太舊,應該都可執行

 








已經找到python file使用中文的方式,開頭給字形
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- 

圖片拉大後可拉小了,要將viewport先加進捲動視窗(如下圖)


多加了檔案列表類別t_filechosser,處理檔選擇器被選取後,把檔案加入TreeView列表中,當TreeView列表被選取時,信號呼叫重新調整image大小後顯示,其實有些可以用Glade來設計,用glade會有些不滿意,乾脆這部份就不用glade,成一個CLASS,日後也可拿來用,譬如音樂播放氣

另外加強image_viewport這類別的功能,能夠保持等比例縮小或放大圖片

程式碼共有4個檔案(一個glade建立的ui檔,3個用Anjuta IDE編輯的py檔)如下

 pygtk_foobar_u1410.ui

 <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
  <requires lib="gtk+" version="3.0"/>
  <object class="GtkFileFilter" id="filefilter1">
    <patterns>
      <pattern>*.jpg</pattern>
      <pattern>*.png</pattern>
      <pattern>*.PNG</pattern>
      <pattern>*.JPG</pattern>
    </patterns>
  </object>
  <object class="GtkListStore" id="liststore1">
    <columns>
      <!-- column-name gchararray1 -->
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkWindow" id="window">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">False</property>
    <property name="vexpand">False</property>
    <property name="title" translatable="yes">圖片檢視器</property>
    <property name="window_position">center</property>
    <property name="default_width">700</property>
    <property name="default_height">502</property>
    <property name="gravity">center</property>
    <signal name="check-resize" handler="IMAGE_RESIZE" object="viewport1" swapped="no"/>
    <signal name="destroy" handler="on_window_destroy" swapped="no"/>
    <child>
      <object class="GtkPaned" id="paned1">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <child>
          <object class="GtkBox" id="box1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="orientation">vertical</property>
            <child>
              <object class="GtkButton" id="button6">
                <property name="label" translatable="yes">  選    擇    圖    片    檔       ...  </property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <signal name="clicked" handler="IMAGE_VIEWER" swapped="no"/>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="button3">
                <property name="label" translatable="yes">離開</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <signal name="clicked" handler="SHOW_IMAGE" object="window" swapped="no"/>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="pack_type">end</property>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <object class="GtkScrolledWindow" id="scrolledwindow1">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="shadow_type">in</property>
                <child>
                  <placeholder/>
                </child>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">2</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="button2">
                <property name="label" translatable="yes">隱藏圖片</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <signal name="clicked" handler="SHOW" object="label1" swapped="no"/>
                <signal name="clicked" handler="SHOW_IMAGE" object="image1" swapped="no"/>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="pack_type">end</property>
                <property name="position">3</property>
              </packing>
            </child>
            <child>
              <object class="GtkLabel" id="label1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="margin_right">4</property>
                <property name="label" translatable="yes">訊息</property>
                <property name="ellipsize">start</property>
                <property name="max_width_chars">0</property>
                <attributes>
                  <attribute name="font-desc" value="<輸入數值> 18"/>
                  <attribute name="style" value="italic"/>
                  <attribute name="weight" value="bold"/>
                  <attribute name="foreground" value="#cccc00000000"/>
                </attributes>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="padding">20</property>
                <property name="position">4</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="button1">
                <property name="label" translatable="yes">顯示圖片</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="yalign">0.44999998807907104</property>
                <signal name="clicked" handler="SHOW" object="label1" swapped="no"/>
                <signal name="clicked" handler="SHOW_IMAGE" object="image1" swapped="no"/>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="pack_type">end</property>
                <property name="position">5</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="button4">
                <property name="label" translatable="yes">縮放</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <signal name="clicked" handler="SHOW" object="label1" swapped="no"/>
                <signal name="clicked" handler="SHOW_TYPE" swapped="no"/>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="pack_type">end</property>
                <property name="position">6</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="button5">
                <property name="label" translatable="yes">擴展</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <signal name="clicked" handler="SHOW" object="label1" swapped="no"/>
                <signal name="clicked" handler="SHOW_TYPE" swapped="no"/>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="pack_type">end</property>
                <property name="position">7</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="resize">False</property>
            <property name="shrink">True</property>
          </packing>
        </child>
        <child>
          <object class="GtkScrolledWindow" id="scrolledwindow2">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="shadow_type">in</property>
            <child>
              <object class="GtkViewport" id="viewport1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="events">GDK_BUTTON_MOTION_MASK | GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK</property>
                <child>
                  <object class="GtkImage" id="image1">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="halign">center</property>
                    <property name="valign">center</property>
                    <property name="stock">gtk-missing-image</property>
                  </object>
                </child>
              </object>
            </child>
          </object>
          <packing>
            <property name="resize">True</property>
            <property name="shrink">True</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>


treeview_filechooser.py


#!/usr/bin/env python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-
# treeview_filechosser.py
#
# Copyright (C) 2015 - root
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#給頂層視窗window參數,容器add_widget參數,和處理圖片的物件view參數,可加入TreeView到容器dd_widget
#call_resize方法中,參數view物件須提供方法i_image_resize,此方法只是來處理,TreeView選項被選取後會呼叫
#此treeview,提供File_open()來打開檔案圖片,選取後加入treeview的表單
#_type_若是"DELETE",選取file,加入treeview會先清空treeview內容,否則一直加上去
from gi.repository import Gtk, GdkPixbuf, Gdk
import sys,os
from gi.repository.GdkPixbuf import Pixbuf, InterpType
class t_filechosser():
 #建構式,用來初始化物件
 def __init__(self,add_widget,window,view,_type_,ifile):
        #inital data
        self._TYPE_=_type_
        self.add_tree_w=add_widget
        self.window=window
        self.image_viewport_new=view
        self.file=ifile
        #新Treeview,要先有store來存放資料
        self.store = Gtk.ListStore(str)
        self.tt=Gtk.TreeView(self.store)
        #Treeview加入
        self.add_tree_w.add(self.tt)
        #建立signal connect
        self.tt.connect('cursor-changed', self.SHOW_ITEM)
        #記得要給TreeViewColumn,否則TreeView無法顯示
        column = Gtk.TreeViewColumn("-----檔名-----", Gtk.CellRendererText(), text=0)
        column.set_sort_column_id(0)
        self.tt.append_column(column)


   
 def File_open(self):
        self.dlg = Gtk.FileChooserDialog(
                "Select Picture",
                self.window,
                Gtk.FileChooserAction.OPEN,
                (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK) )
        self.dlg.show()
        print("開啟檔案選擇器")
        self.dlg.set_default_response(Gtk.ResponseType.CANCEL)
        self.dlg. set_select_multiple(True)


        #可用glade加檔案過濾器
        #self.dlg.add_filter(self.filefilter1)
        #加檔案過濾器'*.jpg','*png','*PNG','*.JPG'   
        lfilter = Gtk.FileFilter()
        lfilter.set_name('Picture')
        flist=list(('*.jpg','*png','*PNG','*.JPG'))
        for fl in flist:
         lfilter.add_pattern(fl)
         print(fl)
        self.dlg.add_filter(lfilter)
        self.dlg.set_filter(lfilter)
        #設定filechosserdialog按鈕事件,按OK加入list,否則destroy
          response = self.dlg.run()
          if response == Gtk.ResponseType.OK:
         if self._TYPE_=="DELETE":self.store.clear()
         #取得選取file list 
         lfile=self.dlg.get_filenames()
           #print(lfile[0])
           #加入treeview list
           for x in lfile:
           #self.liststore1.append([x])
           self.store.append([x])
           #self.image_viewport_new.i_image_resize(lfile[0])
           self.tt.set_cursor(0)
       
         self.dlg.destroy()
          elif response == Gtk.ResponseType.CANCEL:
              print("Cancel clicked")
        #注意最後要destroy,讓使用者按左上x能關閉 
          self.dlg.destroy()                                                 
       
    #連結信號,設定顯示的樣式
 def SHOW_ITEM(self, widget,*event):
        try :
         sel=self.tt.get_selection()
         (model,iter)=sel.get_selected()
         self.file=list(model[iter])[0]
         #取得image_viewport_new物件的i_image_resize來重設圖片大小
         #self.image_viewport_new.i_image_resize(self.file)
         self.call_resize()
         print(list(model[iter])[0])
        except:pass
 def call_resize(self):
     try :
        self.image_viewport_new.i_image_resize(self.file)
     except:print("請給一個物件的方法i_image_resize,來處理TreeView選項被選取")



size_image.py



#!/usr/bin/env python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-
#image_viewport類別,是用來重設圖片大小
#給一個image參數, viewport參數,i_type參數,產生物件,此物件提供調整圖片大小的i_image_resize方法
#image是顯示該圖片的widget
#viewport是放image的容器
#i_type給任何字串,圖片會調到和viewprt一樣大,若設定"縮放",照圖片等比例調整
#i_image_resize(self,filepath)給圖片filepath,重設圖片大小
#is_viewpot_change(self,widget)給viewport,判定viewport是否改變
#為什要判定viewport是否改變,譬如給check-resize信號用來判斷,當使用者拉大視窗一下,
#連結調整圖片,載入圖片時,會觸發check-resizecheck-resize又會呼叫調整圖片,變成迴圈

from gi.repository import Gtk, GdkPixbuf, Gdk
import sys,os
from gi.repository.GdkPixbuf import Pixbuf, InterpType
class image_viewport():
 #建構式,用來初始化物件
 def __init__(self,image, viewport,i_type):
        #inital data
        self.w_size=0
        self.h_size=0
        self.image = image
        self.viewport = viewport
        self.i_type=i_type

 #定義了一些取得設定物件成員值
 def i_get_viewport_h_size(self):
       return self.h_size
 def i_get_viewport_w_size(self):
       return self.w_size
 def i_set_show_type(self,i_type):
       self.i_type= i_type
 def i_get_show_type(self):
       return self.i_type
 def is_viewpot_change(self,widget):
        #目前viewport size
        boolean=False
        w_size=widget.get_allocation().width
        h_size=widget.get_allocation().height       
        #檢查viewport是否改變,若是回傳值True
        if(self.w_size!=w_size or self.h_size!=h_size ):
           boolean=True
        return boolean   

 #定義重設視窗的方法      
 def i_image_resize(self,filepath):
        self.h_size=self.viewport.get_allocation().height
        self.w_size=self.viewport.get_allocation().width
        #從filepath產生圖片buffer
        pixbuf = Pixbuf.new_from_file(filepath)
        #orange image size
        iw=pixbuf.get_width()
        ih=pixbuf.get_height()
        #參數先轉成float
        w,h=change_width_height(self,float(iw),float(ih),float(self.w_size),float(self.h_size))
        print("width" ,w)
        print("height",h)
       
        #重設圖片buffer寬高
        pixbuf = pixbuf.scale_simple(w, h, InterpType.BILINEAR)
        #把圖片buffer放到image widget
        self.image.set_from_pixbuf(pixbuf)
       

#定義方法,用來計算圖片新的寬高,並回傳寬和高
def change_width_height(self,ix,iy,vx,vy):

      #預設回傳viewport寬和高
      width=vx
      height=vy
      cy=iy/vy
      cx=ix/vx
      #print(cy)
      #print(self.i_type)

      #判斷image與viewport比例,顯示若是EXTEND形式,設定新的寬和高
      if cx >= cy and self.i_type=="縮放":
      
       try:
        #new size
        width=ix/cx
        height=iy/cx
       except:pass
      if cy >= cx and self.i_type=="縮放":
       try:
        #new size
        width=ix/cy
        height=iy/cy
       except:pass
      
      return width,height
      #結束def change_width_height end



 主程式pygtk_foobar_u1410.py









#!/usr/bin/env python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-
#
# main.py
# Copyright (C) 2015 yplin
#
# pygtk-foobar_u1410 is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pygtk-foobar_u1410 is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see .

from gi.repository import Gtk, GdkPixbuf, Gdk

import os, sys ,size_image,treeview_filechooser
import glob
from gi.repository.GdkPixbuf import Pixbuf, InterpType

#Comment the first line and uncomment the second before installing
#or making the tarball (alternatively, use project variables)
UI_FILE = "src/pygtk_foobar_u1410.ui"
#UI_FILE = "/usr/local/share/pygtk_foobar_u1410/ui/pygtk_foobar_u1410.ui"


class GUI:
    def __init__(self):
        #新建了一個xml-gtk
        self.builder = Gtk.Builder()
        #把UI_FILE加到gtk,glade產生的xml
        self.builder.add_from_file(UI_FILE)
        #建立xml信號連結
        self.builder.connect_signals(self)
        #取得xml UI上所有元件
        self.file="src/logo.png"
        self.test_w=0
        self.test_h=0
        self.label=self.builder.get_object('label1')
        self.button2=self.builder.get_object('button2')
        self.button1=self.builder.get_object('button1')
        self.button3=self.builder.get_object('button3')
        self.window=self.builder.get_object('window')
        self.fixed=self.builder.get_object('fixed1')
        self.image=self.builder.get_object('image1')
        self.viewport=self.builder.get_object('viewport1')
        self.treeview=self.builder.get_object('treeview1')
        self.liststore1=self.builder.get_object('liststore1')
        self.filefilter1=self.builder.get_object('filefilter1')
        self.scrolledwindow1=self.builder.get_object('scrolledwindow1')
        self.image.set_from_file(self.file)
        #self.dlg=self.builder.get_object('filechooserdialog1')
       

        #初始化
       
        #self.treeview.append_column(column)
        #初始化,產生自定義image_viewport ,t_filechosser CLASS
        self.image_viewport_new=size_image.image_viewport(self.image,self.viewport,"擴展")
        self.t_filechosser=treeview_filechooser.t_filechosser(self.scrolledwindow1,self.window,self.image_viewport_new,"DELETE",self.file)
       
    def on_window_destroy(self, widget, *event):
        Gtk.main_quit()
    def on_window_destroy1(self, widget, *event):
        print("HHHHHHHHHHH")


   
   
    #button click 連結信號   
    def SHOW(self, widget, *event):
        print("DDDD")
        #self.label.set_text(self.button2.get_label())
        try:
         #get_focus可取得激活對象
         bt_active_label=self.window.get_focus().get_label()
         #widget是指信號處理對象,用GALADE創建UI時,是為label1
         widget.set_text(bt_active_label)
        except:pass
        #除錯技巧,印出
        #重設label位置
        #self.fixed.put(self.label, 80, 40)


       
       
    #button click 連結信號       
    def SHOW_IMAGE(self, widget, *event):
        #取得激活對象按鈕名稱
        bt_active_label=self.window.get_focus().get_label()
        #根據按鈕名稱,顯示或隱藏圖片
        if bt_active_label=='隱藏圖片':widget.hide()
        if bt_active_label=='顯示圖片':widget.show()
        if bt_active_label=="離開":Gtk.main_quit()
       

    #Window chec-resize連結信號,重設圖片大小
    def IMAGE_RESIZE(self, widget, *event):
        #目前viewport size
        #w_size=self.viewport.get_allocation().width
        #h_size=self.viewport.get_allocation().height
        #存在記憶體viewport size
        #wv=self.image_viewport_new.i_get_viewport_w_size()
        #hv=self.image_viewport_new.i_get_viewport_h_size()

       
        #檢查viewport是否改變,重設size,否則成為無窮迴圈
        if self.image_viewport_new.is_viewpot_change(widget) :
           #print(str(h_size))
           #resize方法,來重設大小方式
           self.t_filechosser.call_resize()

    #連結信號,設定顯示的樣式
    def SHOW_TYPE(self, *event):
        b_label=self.window.get_focus().get_label()
        self.image_viewport_new.i_set_show_type(b_label)
        #resize方法,重設大小方式
        self.t_filechosser.call_resize()
       
        print(0 > 3)
       
    def IMAGE_VIEWER(self, *event):
       
        self.t_filechosser.File_open()
       
       
def main():
    app = GUI()
    app.window.show_all()
    Gtk.main()
   
   
if __name__ == "__main__":
    sys.exit(main())

     

read more...

2015年1月24日 星期六

pygtk圖片,隨著視窗改變大小(更新)


 寫了一個image_viewport類別,繼承Gtk.Image,其實還不熟,沒呼叫super,先不管這有沒有,看重點__init__(self,image, viewport)是建構式,初始化物件,self是自帶,就image,viewport這2個參數,
 其實我只用到3個方法def i_get_viewport_h_size,def i_get_viewport_w_size,def i_image_resize(self,widget,viewport,filepath),不知為什用Anjata在開的副程式file,註解打中文,無法執行,註解只好敲我超爛程度的英文

size_image.py程式

from gi.repository import Gtk, GdkPixbuf, Gdk
import sys,os
from gi.repository.GdkPixbuf import Pixbuf, InterpType
class image_viewport(Gtk.Image):

 def __init__(self,image, viewport):
        #inital data
        self.w_size=0
        self.h_size=0
        self.image = image
        self.viewport = viewport
 def i_set_image(self,image):
       self.image= image
     
 def i_get_image(self,image):
       return self.image
 def i_set_viewport(self,viewport):
       self.viewport= viewport
 def i_get_viewport(self):
       return self.viewport
 def i_get_viewport_h_size(self):
       return self.h_size
 def i_get_viewport_w_size(self):
       return self.w_size     
     
 def i_image_resize(self,widget,viewport,filepath):
    
        self.h_size=viewport.get_allocation().height
        self.w_size=viewport.get_allocation().width
        #put image to buffer
        pixbuf = Pixbuf.new_from_file(filepath)
        #reset size
        pixbuf = pixbuf.scale_simple(self.w_size, self.h_size, InterpType.BILINEAR)
        #set buffer to image
        widget.set_from_pixbuf(pixbuf)

 在主程式,一開始,初始化產生了一個image_viewport實體,叫self.image_viewport_new
        #初始化,產生自定義image_viewport CLASS
        self.image_viewport_new=size_image.image_viewport(self.image,self.viewport)

在主程式,IMAGE_VIEWER是檔案選擇器按鈕,連結信號method

 def IMAGE_VIEWER(self, widget, *event):
        #取得file
        self.file=self.filechooserbutton.get_filename()
        #i_image_resize方法,image跟viewport一樣大小
        self.image_viewport_new.i_image_resize(widget,self.viewport,self.file)


在主程式,IMAGE_RESIZE是window,check-resize連結信號method,注意要判斷,否則信號會變迴圈,一直發出信號
  
    def IMAGE_RESIZE(self, widget, *event):
      
        #目前viewport size
        w_size=self.viewport.get_allocation().width
        h_size=self.viewport.get_allocation().height
        #存在記憶體viewport size
        wv=self.image_viewport_new.i_get_viewport_w_size()
        hv=self.image_viewport_new.i_get_viewport_h_size()

      
        #檢查viewport是否改變,重設size,否則成為無窮迴圈
        if(wv!=w_size or hv!=h_size ):
           print(str(h_size))
           self.image_viewport_new.i_image_resize(widget,self.viewport,self.file)



下圖是GLADE建的window信號check-resize


主程式


#!/usr/bin/env python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-
#
# main.py
# Copyright (C) 2015 yplin
#
# pygtk-foobar_u1410 is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pygtk-foobar_u1410 is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see .

from gi.repository import Gtk, GdkPixbuf, Gdk

import os, sys ,size_image

from gi.repository.GdkPixbuf import Pixbuf, InterpType

#Comment the first line and uncomment the second before installing
#or making the tarball (alternatively, use project variables)
UI_FILE = "src/pygtk_foobar_u1410.ui"
#UI_FILE = "/usr/local/share/pygtk_foobar_u1410/ui/pygtk_foobar_u1410.ui"


class GUI:
    def __init__(self):
        #新建了一個xml-gtk
        self.builder = Gtk.Builder()
        #把UI_FILE加到gtk,glade產生的xml
        self.builder.add_from_file(UI_FILE)
        #建立xml信號連結
        self.builder.connect_signals(self)
        #取得xml UI上所有元件
        self.file="/home/yplin/lion.png"
        self.test_w=0
        self.test_h=0
        self.label=self.builder.get_object('label1')
        self.button2=self.builder.get_object('button2')
        self.button1=self.builder.get_object('button1')
        self.button3=self.builder.get_object('button3')
        self.window=self.builder.get_object('window')
        self.fixed=self.builder.get_object('fixed1')
        self.filechooserbutton=self.builder.get_object('filechooserbutton1')
        self.image=self.builder.get_object('image1')
        self.viewport=self.builder.get_object('viewport1')
        self.image.set_from_file(self.file)
        #初始化,產生自定義image_viewport CLASS
        self.image_viewport_new=size_image.image_viewport(self.image,self.viewport)
       
    def on_window_destroy(self, widget, *event):
        Gtk.main_quit()
   
   
       
    def SHOW(self, widget, *event):
       
        #self.label.set_text(self.button2.get_label())
        #get_focus可取得激活對象
        bt_active_label=self.window.get_focus().get_label()
        #widget是指信號處理對象,用GALADE創建UI時,是為label1
        widget.set_text(bt_active_label)
        #print(user_data)
        #widget.hide()
        #除錯技巧,印出
        #print(str(self.window.get_focus().get_label()))
        #self.button1.set_label("JJJJJJ")
        #重設label位置
        #self.fixed.put(self.label, 80, 40)
    def SHOW_IMAGE(self, widget, *event):
        #取得激活對象按鈕名稱
        bt_active_label=self.window.get_focus().get_label()
        #根據按鈕名稱,顯示或隱藏圖片
        if bt_active_label=='隱藏圖片':widget.hide()
        if bt_active_label=='顯示圖片':widget.show()
        if bt_active_label=="離開":Gtk.main_quit()
    def IMAGE_VIEWER(self, widget, *event):
        #取得file
        self.file=self.filechooserbutton.get_filename()
        #i_image_resize方法,image跟viewport一樣大小
        self.image_viewport_new.i_image_resize(widget,self.viewport,self.file)
   
    def IMAGE_RESIZE(self, widget, *event):
       
        #目前viewport size
        w_size=self.viewport.get_allocation().width
        h_size=self.viewport.get_allocation().height
        #存在記憶體viewport size
        wv=self.image_viewport_new.i_get_viewport_w_size()
        hv=self.image_viewport_new.i_get_viewport_h_size()

       
        #檢查viewport是否改變,重設size,否則成為無窮迴圈
        if(wv!=w_size or hv!=h_size ):
           print(str(h_size))
           self.image_viewport_new.i_image_resize(widget,self.viewport,self.file)
       

         

         
       
       
def main():
    app = GUI()
    app.window.show()
    Gtk.main()
   
   
if __name__ == "__main__":
    sys.exit(main())

執行後如下,圖片是跟著視窗大小跑,可拉大,圖片跟著拉大,但拉大後,不能拉小,應該是Pixbuf的BUG,因為我把圖片隱藏,視窗是可拉小的







好久沒寫程式,犯了一些錯,總覺的有點那不好,不對勁,後來想到了,我已給image,viewport初始化了,記憶體已有image,viewport,在給image,viewport參數會蓋掉原先,呼喚太多次,小程式沒差,程式很大,就有差了,好的設計是越簡單,記憶體用越少越好,會給使用者更好的感受.

   #初始化,產生自定義image_viewport CLASS
        self.image_viewport_new=size_image.image_viewport(self.image,self.viewport)


def i_image_resize(self,widget,viewport,filepath):
    
       這樣寫不好,給filepath參數就可,因為參數在給image(widget),wiewport(viewport),多餘了,程式沒效率,應像下面這樣
 def i_image_resize(self,filepath):

改寫後(紅色地方是改寫地方)

size_image.py程式

from gi.repository import Gtk, GdkPixbuf, Gdk
import sys,os
from gi.repository.GdkPixbuf import Pixbuf, InterpType
class image_viewport(Gtk.Image):

 def __init__(self,image, viewport):
        #inital data
        self.w_size=0
        self.h_size=0
        self.image = image
        self.viewport = viewport
 def i_set_image(self,image):
       self.image= image
      
 def i_get_image(self,image):
       return self.image
 def i_set_viewport(self,viewport):
       self.viewport= viewport
 def i_get_viewport(self):
       return self.viewport
 def i_get_viewport_h_size(self):
       return self.h_size
 def i_get_viewport_w_size(self):
       return self.w_size      
      
 def i_image_resize(self,filepath):
   
        self.h_size=self.viewport.get_allocation().height
        self.w_size=self.viewport.get_allocation().width
        #put image to buffer
        pixbuf = Pixbuf.new_from_file(filepath)
        #reset size
        pixbuf = pixbuf.scale_simple(self.w_size, self.h_size, InterpType.BILINEAR)
        #set buffer to image
        self.image.set_from_pixbuf(pixbuf)


主程式:

#!/usr/bin/env python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-
#
# main.py
# Copyright (C) 2015 yplin
#
# pygtk-foobar_u1410 is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pygtk-foobar_u1410 is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see .

from gi.repository import Gtk, GdkPixbuf, Gdk

import os, sys ,size_image

from gi.repository.GdkPixbuf import Pixbuf, InterpType

#Comment the first line and uncomment the second before installing
#or making the tarball (alternatively, use project variables)
UI_FILE = "src/pygtk_foobar_u1410.ui"
#UI_FILE = "/usr/local/share/pygtk_foobar_u1410/ui/pygtk_foobar_u1410.ui"


class GUI:
    def __init__(self):
        #新建了一個xml-gtk
        self.builder = Gtk.Builder()
        #把UI_FILE加到gtk,glade產生的xml
        self.builder.add_from_file(UI_FILE)
        #建立xml信號連結
        self.builder.connect_signals(self)
        #取得xml UI上所有元件
        self.file="/home/yplin/lion.png"
        self.test_w=0
        self.test_h=0
        self.label=self.builder.get_object('label1')
        self.button2=self.builder.get_object('button2')
        self.button1=self.builder.get_object('button1')
        self.button3=self.builder.get_object('button3')
        self.window=self.builder.get_object('window')
        self.fixed=self.builder.get_object('fixed1')
        self.filechooserbutton=self.builder.get_object('filechooserbutton1')
        self.image=self.builder.get_object('image1')
        self.viewport=self.builder.get_object('viewport1')
        self.image.set_from_file(self.file)
        #初始化,產生自定義image_viewport CLASS
        self.image_viewport_new=size_image.image_viewport(self.image,self.viewport)
       
    def on_window_destroy(self, widget, *event):
        Gtk.main_quit()
   
   
       
    def SHOW(self, widget, *event):
       
        #self.label.set_text(self.button2.get_label())
        #get_focus可取得激活對象
        bt_active_label=self.window.get_focus().get_label()
        #widget是指信號處理對象,用GALADE創建UI時,是為label1
        widget.set_text(bt_active_label)
        #print(user_data)
        #widget.hide()
        #除錯技巧,印出
        #print(str(self.window.get_focus().get_label()))
        #self.button1.set_label("JJJJJJ")
        #重設label位置
        #self.fixed.put(self.label, 80, 40)
    def SHOW_IMAGE(self, widget, *event):
        #取得激活對象按鈕名稱
        bt_active_label=self.window.get_focus().get_label()
        #根據按鈕名稱,顯示或隱藏圖片
        if bt_active_label=='隱藏圖片':widget.hide()
        if bt_active_label=='顯示圖片':widget.show()
        if bt_active_label=="離開":Gtk.main_quit()
    def IMAGE_VIEWER(self, widget, *event):
        #取得file
        self.file=self.filechooserbutton.get_filename()
        #i_image_resize方法,image跟viewport一樣大小
        self.image_viewport_new.i_image_resize(self.file)
   
    def IMAGE_RESIZE(self, widget, *event):
       
        #目前viewport size
        w_size=self.viewport.get_allocation().width
        h_size=self.viewport.get_allocation().height
        #存在記憶體viewport size
        wv=self.image_viewport_new.i_get_viewport_w_size()
        hv=self.image_viewport_new.i_get_viewport_h_size()

       
        #檢查viewport是否改變,重設size,否則成為無窮迴圈
        if(wv!=w_size or hv!=h_size ):
           print(str(h_size))
           self.image_viewport_new.i_image_resize(self.file)
       

         

         
       
       
def main():
    app = GUI()
    app.window.show()
    Gtk.main()
   
   
if __name__ == "__main__":
    sys.exit(main())



read more...

2015年1月23日 星期五

用pygtk寫的圖片檢視器

前面有教過GLADE產生gtk ui,現在使用GLADE再產生filechosserbutton(檔案選擇器按鈕),如下圖左上角,訊號處理打上一個method(這我打上IMAGE_VIEWER),使用者資料選image(這裡我選image1),下面MAGE_VIEWE就是處理檔案選擇器按鈕被按下後的方法


def IMAGE_VIEWER(self, widget, *event):
        file=self.filechooserbutton.get_filename()
        #print(str(self.filechooserbutton.get_current_folder_uri()))
        #print(str(file))
        widget.set_from_file(file)



看一下pygtk手冊filechosserbutton繼承如下,在FileChooser找到取得file名稱的方法get_filename(),

+-- gobject.GObject
  +-- gtk.Object
    +-- gtk.Widget
      +-- gtk.Container
        +-- gtk.Box
           +-- gtk.HBox
             +-- gtk.FileChooserButton (implements gtk.FileChooser)
 
 file=self.filechooserbutton.get_filename()取得file路徑名稱的方法
 widget.set_from_file(file)把imgage設成 file,圖片就改變了,widget變數是指信號處理對象(GLADE敲入IMAGE_VIEWER信號時,選的那個信號處理對象)
 
 再來是用GLADE產生檔案過濾器,我只想要jpg或png檔,如下圖1,filechooserbutton的一般條件選filefilter1,動作選開啟
 b然後widgets會出現filter1,點它,如下圖2,一般的模式中敲入要過濾條件(*.jpg......),如此,filechooser只會顯示過濾條件的檔案
 
 


python程式如下

 #!/usr/bin/env python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-
#
# main.py
# Copyright (C) 2015 yplin
#
# pygtk-foobar_u1410 is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pygtk-foobar_u1410 is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see .

from gi.repository import Gtk, GdkPixbuf, Gdk

import os, sys


#Comment the first line and uncomment the second before installing
#or making the tarball (alternatively, use project variables)
UI_FILE = "src/pygtk_foobar_u1410.ui"
#UI_FILE = "/usr/local/share/pygtk_foobar_u1410/ui/pygtk_foobar_u1410.ui"


class GUI:
    def __init__(self):
        #新建了一個xml-gtk
        self.builder = Gtk.Builder()
        #把UI_FILE加到gtk,glade產生的xml
        self.builder.add_from_file(UI_FILE)
        #建立xml信號連結
        self.builder.connect_signals(self)
        #取得xml UI上所有元件
        self.label=self.builder.get_object('label1')
        self.button2=self.builder.get_object('button2')
        self.button1=self.builder.get_object('button1')
        self.button3=self.builder.get_object('button3')
        self.window=self.builder.get_object('window')
        self.fixed=self.builder.get_object('fixed1')
        self.filechooserbutton=self.builder.get_object('filechooserbutton1')
        self.image=self.builder.get_object('image1')
        self.image.set_from_file("/home/yplin/lion.png")
    def on_window_destroy(self, widget, *event):
        Gtk.main_quit()
   
   
       
    def SHOW(self, widget, *event):
       
        #self.label.set_text(self.button2.get_label())
        #get_focus可取得激活對象
        bt_active_label=self.window.get_focus().get_label()
        #widget是指信號處理對象,用GALADE創建UI時,是為label1
        widget.set_text(bt_active_label)
        #print(user_data)
        #widget.hide()
        #除錯技巧,印出
        #print(str(self.window.get_focus().get_label()))
        #self.button1.set_label("JJJJJJ")
        #重設label位置
        #self.fixed.put(self.label, 80, 40)
    def SHOW_IMAGE(self, widget, *event):
        #取得激活對象按鈕名稱
        bt_active_label=self.window.get_focus().get_label()
        #根據按鈕名稱,顯示或隱藏圖片
        if bt_active_label=='隱藏圖片':widget.hide()
        if bt_active_label=='顯示圖片':widget.show()
        if bt_active_label=='離開':Gtk.main_quit()
    def IMAGE_VIEWER(self, widget, *event):
        #取得file
        file=self.filechooserbutton.get_filename()
        #print(str(self.filechooserbutton.get_current_folder_uri()))
        #print(str(file))
        #file加入image
        widget.set_from_file(file)
def main():
    app = GUI()
    app.window.show()
    Gtk.main()
   
   
if __name__ == "__main__":
    sys.exit(main())

執行的樣子











 

read more...