ווטסאפ - לינוקס, BSD, קוד פתוח ותוכנה חופשית בעברית. Whatsup - Linux, BSD, open source and free software in Hebrew

 
 
  כניסת חברים · רישום · שכחתי סיסמה  
tux the penguin

quick_linkמדריך: פייתון, glade ורכיבים מותאמים אישית

published at 10/03/2006 - 15:38 · ‏פורסם mksoft · ‏tags פיתוח , מדריכים ומגזינים · שלח לחברידידותי למדפסת
פיתוח

במסגרת עבודתי על פרוייקט המבוסס על PyGTK, נזקקתי לרכיב Entry בעל יכולת אימות התוכן והצגת חיווי למשתמש במקרה של אי התאמה. היה צורך לאפשר להשתמש ברכיב בממשקים המתוכננים בעזרת גלייד. הוחלט לכתוב רכיב כזה בפייתון ולא ב-C כדי למנוע בעיות הידור, אריזה והפצה (הפרוייקט עובד על מספר פלטפורמות). בפייתון נוכל פשוט לכלול אותו עם שאר הקוד של הפרוייקט ולבצע לו import. בנוסף פייתון נוחה יותר לכתיבה ;-)

המדריך מתאר את כתיבת הרכיב והגדרת סיגנל נוסף עבורו, שימוש ברכיבים המותאמים אישית של גלייד (או גאספאצ'ו) ושילובו ביישום.



תוכן:

מנגנון הרכיבים המותאמים של גלייד ושילובם ב-PyGTK
הרכיב המותאם אישית
יישום דוגמא
הורדת הקוד

מנגנון הרכיבים המותאמים של גלייד ושילובם ב-PyGTK

<img src="whatsup/images/articles/glade_custom.png" alt="glade custom properties" style="float:left;"/> כאשר משתמשים ברכיב מותאם בגלייד, מגדירים עבורו, חוץ משם הרכיב אשר משותף לכל הרכיבים, 5 משתנים:

* שם פונקציית היצירה: create_func, מחרוזת שתועבר לקוד אשר יחליט לפיה איזה רכיב ליצור.

* שתי מחרוזות: String1 ו-String2, משתנים שברצוננו להעביר לרכיב.

* שני מספרים: Int1 ו-Int2, גם הם יועברו לרכיב

המשתנים האלה מועברים לפונקציה שתוגדר על ידינו, ובעזרתם ניתן ליצור את הרכיבים המותאמים שלנו.

הרכיב המותאם אישית

<img src="whatsup/images/articles/custom_widget.png" alt="custom widget" style="float:left;"/> כדי לשמור על גמישות באופן האימות של הרכיב, הוחלט להשתמש בביטויים רגולריים. הרכיב יציג תמונה לצד השדה במקרה של בעיה וטיפ (tooltip) כאשר מצביע העכבר מעל התמונה או השדה. במקרה שהכל תקין, התמונה תיעלם והטיפים ינוטרלו.

<img src="whatsup/images/articles/glade_custom_cellular.png" alt="custom cellular" style="float:left;"/> String1 יהיה הביטוי הרגולרי, String2 יהיה הטיפ, ו-Int1 יהיה מספר התווים המקסימלי בשדה. Int2 לא יהיה בשימוש, ופשוט נתעלם ממנו.

הרכיב הבסיסי משתמש ב-HBox עם שני אלמנטים. הראשון יחזיק את השדה, והשני את התמונה. מכיוון שלתמונה אין חלון משלה (ולכן לא מקבלת events וכן הלאה), החלק השני יכיל EventBox ובתוכו תשב התמונה. הרכיב מאזין לאירוע changed של השדה, ועם כל שינוי, מאמת מול הביטוי הרגולרי ומפעיל/מנטרל את התמונה והטיפים לפי הצורך.

הקוד די מדבר בעד עצמו:

regex_entry.py
import gtk
import gobject
import re

class RegexEntry(gtk.HBox):
    """ Implements a regular expression matching entry, with a state 
    icon.
    
    signals:
        'changed' : triggerd when the child entry changes. Updates the icon
                    and tooltips visibility prior to emition.
    """
    
    __gsignals__ = {
        'changed': ( gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, () )
    }
    
    def __init__(self, str1, str2, int1, int2):
        '''Creates the regex entry
        
        @param str1: The Regular expression
        @param str2: Tooltip in case of invalid entry
        @param int1: Max length of the entry
        @param int2: Unused
        '''
        
        gtk.HBox.__init__(self)
        
        # our regular expression
        self._re = re.compile(str1)
        
        # create the entry, listen to it's changed event
        self.entry = gtk.Entry()
        self.entry.set_max_length(int1)
        self.entry.connect("changed", self.entry_changed)
        
        # our icon
        self.icon = gtk.Image()
        self.icon.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_BUTTON)
        
        # Event box holding the icon
        self.eventbox = gtk.EventBox()
        self.eventbox.add(self.icon)
        
        # add the children and make them visible
        self.pack_start(self.entry)
        self.pack_end(self.eventbox, False, True, 2)
        
        self.show_all()
        
        # the tooltips object for the widgets
        self.tooltips = gtk.Tooltips()
        
        self.tooltips.set_tip(self.eventbox, str2)
        self.tooltips.set_tip(self.entry, str2)

        # Make sure the icon/tooltips are in the right statr
        self.entry_changed(self.entry)
        
    def set_text(self, text):
        ''' Sets the entry's text
        
        @param text: The text for the entry
        '''
        self.entry.set_text(text)
        
        
    def get_text(self):
        '''Returns the text in the entry'''
        
        return self.entry.get_text()
    
    def entry_changed(self, widget):
        ''' Listens to changes in the entry and sets the notification elements
        
        @param widget: Widget generating the event. Passed by gobject
        '''
        
        # found the match ?
        if self._re.search(self.entry.get_text()):
            self.eventbox.hide()
            self.tooltips.disable()
        else:
            self.eventbox.show()
            self.tooltips.enable()
        
        # notify those listening to the changed event if needed.
        self.emit('changed')

    def is_valid(self):
        '''Returns validity state of the widget'''
        
        return not self.eventbox.get_property("visible")


יישום דוגמא

<img src="whatsup/images/articles/demo_custom.png" alt="Demo app" style="float:left;"/> לצורך הדגמה ניצור 2 שדות. אחד יבקש שם שחובה להזינו, ושני הוא מספר פלאפון אופציונלי. ניתן להשאירו ריק, אך אם הוקלד תוכן, התוכן אמור להיות מספר פלאפון חוקי. לחצן האישור יופעל וינוטרל בהתאם לחוקיות תוכן השדות.

הרכיב המותאם אישית בגלייד נמצא בעמוד של GTK+Additional, בעל צלמית המכילה את האות C:
<img src="whatsup/images/articles/glade_palette.png" alt="palette button"/>

היישום הוא יישום גלייד די סטנדרטי. שני הדברים שיש לשים אליהם לב הם הקריאה ל-gtk.glade.set_custom_handler והפונקציה שלנו שמחזירה את הרכיב. חשוב לזכור שיש לקרוא ל-set_custom_handler לפני שטוענים קובץ גלייד כדי שהוא יידע ליצור את הרכיבים.

שימו לב גם לקשירת סיגנל ה-change שיצרנו ב-RegexEntry ל-on_custom_changed. שם הפונקציה הוגדר בקובץ הגלייד, תחת שם זהה עבור שני רכיבי ה-custom שלנו.

demo.py
import gtk, gtk.glade
import regex_entry
import os

def our_handler(glade, function_name, widget_name, str1, str2, int1 , int2):
    """ the handler should return the widgets, based on function_name """
    if function_name == "regex_entry":
        return regex_entry.RegexEntry(str1, str2, int1, int2)

class MainWindow(object):

    def __init__(self):
        xml = gtk.glade.XML("project2.glade", "main_window")
        window = xml.get_widget("main_window")
        window.connect("destroy", self.quit)

        self.btn_ok = xml.get_widget("buttonOK")
        self.name = xml.get_widget("customName")
        self.cellular= xml.get_widget("customCellular")

        xml.signal_autoconnect(self)

        # set initial state of OK button
        self.on_custom_changed(None)

    def on_buttonCancel_clicked(self, widget):
        """Quit on cancel"""
        self.quit(widget)
        	
    def on_buttonOK_clicked(self, widget):
        """Print name,celluar and exit"""
        
        print self.name.get_text(), self.cellular.get_text()
        self.quit(widget)
        
    def on_custom_changed(self, widget):
        """Listens to change visual warnings state depending on
        validity state"""
        
        self.btn_ok.set_sensitive( self.name.is_valid() and self.cellular.is_valid() )
        
    def quit(self, widget):
        gtk.main_quit()

    def run(self):
        gtk.main()

if __name__ == "__main__":
    # this is important part: sets the custom handler
    gtk.glade.set_custom_handler(our_handler)
    main_window = MainWindow()
    main_window.run()


הורדת הקוד

הקוד ופרוייקט הגלייד זמינים להורדה. אם מסיבה כלשהי תרצו להשתמש ברכיב, הוא תחת רישיון LGPL. הקוד עצמו תחת GPL.

 

קישורים רלוונטיים

· עוד על פיתוח
· חדשות מאת mksoft


הסיפור הנקרא ביותר בנושא פיתוח:
הטבלה המחזורית של האופרטורים

מדריך: פייתון, glade ורכיבים מותאמים אישית | כניסה / יצירת מנוי חדש | 5 תגובות
סף חסימה
  
ההערות הינן מטעם כותביהן. אין צוות האתר לוקח אחריות על תוכנן
Re: מדריך: פייתון, glade ורכיבים מותאמים אישית (ניקוד: 1)
ע"י yoramfr ב 11/03/2006 - 06:21

(מידע על משתמש | שלח הודעה)
הכל טוב ויפה, אבל אני עוד לא מצאתי איך מדפיסים במדפסת, דף מעוצב, ב:
Python, PyGtk, PyQt
כאשר עושים תוכנה משרדית כל שהיא, צריך פלט נייר מעוצב. למשל חשבוניות, תעודות משלוח,
הזמנות, וכדומה.
אם מישהוא כאן יכול לעזור לי בנושא, אני אורה לו מכל הלב.

[ השב לזאת ]


Re: מדריך: פייתון, glade ורכיבים מותאמים אישית (ניקוד: 0)
ע"י פינגווין אנונימי ב 11/03/2006 - 11:24
שלום,

הכנתי תכנית דוגמא, אני מקווה שהתכנית הזו מסבירה בצורה פשוטה דרך אחת להדפיס עם pyGTK.

קישור לתכנית
http://libhdate.sourceforge.net/debian/files/heb_print.py

קישור להסבר מפורט יותר באתר של pyGTK
http://www.pygtk.org/pygnomeprint/gnomeprint-class-reference.html

קובי.







Re: מדריך: פייתון, glade ורכיבים מותאמים אישית (ניקוד: 0)
ע"י פינגווין אנונימי ב 11/03/2006 - 11:26
מאיר: שכחתי לציין, מאוד אהבתי את המדריך :-)

קובי.





Re: מדריך: פייתון, glade ורכיבים מותאמים אישית(ניקוד: 1)
ע"י mksoft (meir@mksoft.co.il)
ב 12/03/2006 - 15:50
(מידע על משתמש | שלח הודעה) http://mksoft.co.il/
תודה. נחמד לקבל משוב חיובי :-)




bookmarks (ניקוד: 0)
ע"י פינגווין אנונימי ב 09/05/2007 - 17:43
href=http://coweb.georgefox.edu:8080/AshleyFisher/uploads/3/free.html>Teen Girl Model Galleries <a

[ השב לזאת ]