2012-05-24 33 views
-1

現在我爲Windows創建了WidgetArea,但主要是Linux用戶。我也想爲Linux做好準備,但主要是爲了更多地瞭解PyGTK中的文件對話框。所以我看了一下this教程,以便更好地理解它,同時開發這個簡單而又小巧的應用程序,因爲這對我來說更容易學習,並通過實驗來理解。PyGTK FileChooserDialog保持錯誤

所以這裏是我的源代碼。

#!/usr/bin/env python 

import sys, os 
import pygtk, gtk, gobject 
import pygst 
pygst.require("0.10") 
import gst 

class WidgetArea(gtk.Window): 

    def addwidget(self, w): 
    self.win = gtk.Window(gtk.WINDOW_TOPLEVEL) 
    self.win.set_title("Widget") 
    self.win.set_decorated(False) 
    self.win.set_has_frame(False) 
    self.win.set_resizable(False) 
    self.win.set_keep_above(True) 
    self.win.set_property('skip-taskbar-hint', True) 
    self.previewimage = gtk.Image() 
    self.win.add(self.previewimage) 
    self.win.show_all() 

    def pinning(self, checkbox): 
    if checkbox.get_active(): 
    self.set_keep_above(True) 
    else: 
    self.set_keep_above(False) 

    def change_size(self, w): 
    width = int(self.entryw.get_text()) 
    height = int(self.entryh.get_text()) 
    self.win.set_size_request(width,height) 

    def __init__(self): 
    super(WidgetArea, self).__init__() 
    self.set_position(gtk.WIN_POS_CENTER) 
    self.set_title("WidgetArea") 
    self.set_resizable(False) 
    self.set_keep_above(True) 
    self.set_property('skip-taskbar-hint', True) 
    self.connect("destroy", gtk.main_quit, "WM destroy") 
    vbox = gtk.VBox(spacing=0) 
    hbox = gtk.HBox(spacing=0) 
    hbox2 = gtk.HBox(spacing=0) 
    hbox3 = gtk.HBox(spacing=0) 
    hbox4 = gtk.HBox(spacing=0) 

    self.widgetsize = gtk.Label("Widget Size:") 
    self.widgetsize.set_size_request(100, 30) 

    self.entryw = gtk.Entry() 
    self.entryh = gtk.Entry() 
    self.entryw.set_text("270") 
    self.entryw.set_size_request(75, 30) 
    labelcoma = gtk.Label(",") 
    labelcoma.set_size_request(10, 30) 
    self.entryh.set_text("221") 
    self.entryh.set_size_request(75, 30) 
    labelspac1 = gtk.Label(" ") 
    labelspac1.set_size_request(10, 30) 
    hbox.pack_start(self.widgetsize) 
    hbox.pack_start(self.entryw) 
    hbox.pack_start(labelcoma) 
    hbox.pack_start(self.entryh) 
    hbox.pack_start(labelspac1, 0, 0, 10) 

    check = gtk.CheckButton("Pin This Window") 
    check.set_active(True) 
    check.connect("clicked", self.pinning) 
    hbox.pack_start(check, 0, 0, 10) 

    labelspac2 = gtk.Label(" ") 
    labelspac2.set_size_request(250, 15) 
    hbox2.pack_start(labelspac2) 

    filefilter = gtk.FileFilter() 
    filefilter.set_name("Images") 
    filefilter.add_mime_type("image/png") 
    filefilter.add_mime_type("image/jpeg") 
    filefilter.add_mime_type("image/gif") 
    filefilter.add_mime_type("image/tiff") 
    filefilter.add_mime_type("image/svg+xml") 
    filefilter.add_pattern("*.jpg") 

    self.ref_file_button = gtk.FileChooserButton('Add Widget') 
    self.ref_file_button.set_current_folder("/".join([self.rootdir,"pics"])) 
    self.ref_file_button.set_filter(filefilter) 
    self.ref_file_button.connect("file-set", self.on_open_clicked) 
    hbox3.pack_start(self.ref_file_button, 150, 150, 10) 

    labelspac5 = gtk.Label(" ") 
    labelspac5.set_size_request(0, 10) 
    hbox4.pack_start(labelspac5) 

    vbox.pack_start(hbox) 
    vbox.pack_start(hbox2) 
    vbox.pack_start(hbox3) 
    vbox.pack_start(hbox4) 
    self.add(vbox) 
    self.show_all() 

    def on_open_clicked(self, widget, data=None): 
    ref_image_path = widget.get_filename() 
    self.previewimage.set_from_file(ref_image_path) 
    self.addwidg.connect("clicked", self.addwidget) 
    self.addwidg.connect("clicked", self.change_size) 
    ref_image_path.destroy() 

WidgetArea() 
gtk.gdk.threads_init() 
gtk.main() 

我刪除了下面的代碼(第1),由於下面的錯誤(第2)。

self.ref_file_button.set_current_folder("/".join([self.rootdir,"pics"])) 

Traceback (most recent call last): 
    File "./widgetarea.py", line 109, in <module> 
    WidgetArea() 
    File "./widgetarea.py", line 86, in __init__ 
    self.ref_file_button.set_current_folder("/".join([self.rootdir,"pics"])) 
AttributeError: 'WidgetArea' object has no attribute 'rootdir' 

現在這在這一點上沒什麼大不了的。我的主要目標是讓圖像顯示在新窗口中。所以在我刪除了上面的代碼之後,由於那個錯誤,我得到了另一個。

Traceback (most recent call last): 
    File "./widgetarea.py", line 103, in on_open_clicked 
    self.previewimage.set_from_file(ref_image_path) 
AttributeError: 'WidgetArea' object has no attribute 'previewimage' 

所有我遇到的問題是,當你瀏覽選擇我要選擇的圖像,按下時確定啓動在該窗口中顯示所選擇的圖像的新窗口中的圖像,如上所述。

回答

1

我在我的一個項目中使用過類似的東西。在Linux中它對我來說很好。

def __init__(self): 
    # Define all the widgets 
    image_filter = gtk.FileFilter() 
    image_filter.set_name("Images") 
    image_filter.add_mime_type("image/png") 
    image_filter.add_mime_type("image/jpeg") 
    image_filter.add_mime_type("image/gif") 
    image_filter.add_mime_type("image/tiff") 
    image_filter.add_mime_type("image/svg+xml") 
    image_filter.add_pattern("*.jpg") 

    self.ref_file_button = gtk.FileChooserButton('Select Image') 
    self.ref_file_button.set_size_request(100,30) 
    self.ref_file_button.set_current_folder("/".join([self.rootdir,"pics"])) # set directory path 
    self.ref_file_button.set_filter(image_filter) 
    self.ref_file_button.set_tooltip_text('Select Image') 
    self.ref_file_button.connect("file-set", self.ref_image_selected) 

def ref_image_selected(self,widget,data=None): 
    ref_image_path = widget.get_filename() 
    print ref_image_path 

獲取圖像的路徑後,您可以使用gtk.Image

加載它

編輯:

你的代碼是有點錯誤的。你永遠不會調用函數addwidget(),因此self.previewimage沒有定義。所以它給了AttributeError。

def __init__(self): 
    # your code 
    self.add(vbox) 
    self.addwidget(200) # I don't know what 'w' is. so I took a random number. 
    self.show_all() 

def on_open_clicked(self, widget, data=None): 
    ref_image_path = widget.get_filename() 
    self.previewimage.set_from_file(ref_image_path) 
    self.addwidg.connect("clicked", self.addwidget) 
    self.addwidg.connect("clicked", self.change_size) 
    ref_image_path.destroy() 

什麼是self.addwidg

我現在可以查看圖像了。

+0

更新的代碼和說明。 –

+1

你的addwidget()函數永遠不會被調用。所以,self.previewimage = gtk.Image()不會發生。所以,它給出的錯誤:AttributeError:'WidgetArea'對象沒有屬性'previewimage' – Froyo

+0

lol我忘了最重要的部分| self.addwidg是一個按鈕,但我刪除了它。大聲笑感謝您的幫助,併爲ptomato。 –

2

要更正第一個錯誤,請使用gtk.FILE_CHOOSER_ACTION_OPEN而不是gtk.FileChooserAction.OPEN

第二個問題是因爲在代碼中沒有名爲image的變量(第116行)。也許你來自C++或Java背景,可以通過查看封閉類的屬性(如this.image)來解析名稱如image

在Python中,你不能這樣做。您必須在您的addwidget()方法中明確指定self.image。否則,名稱image保持在addwidget()方法的本地,並且在其外部不可用。

這引發了一個不同的問題,每次按鈕被點擊並調用addwidget()時會發生什麼? self.winself.image被覆蓋。這可能是你想要的,但我只是把它叫到你的注意---這對我來說似乎有點奇怪。