2012-01-30 27 views
6

Tôi muốn có cửa sổ hộp thoại trong đó một số nút đóng hộp thoại và các nút khác thì không. Cách tôi thực hiện việc này là sử dụng tín hiệu response từ số Gtk.Dialog để gọi emit_stop_by_name('response') trên hộp thoại. (Nếu ai đó biết cách làm tốt hơn, điều đó có thể coi thường toàn bộ phần còn lại của câu hỏi này.)Hộp thoại ngắt khi sử dụng GtkBuilder để tự động kết nối tín hiệu, nhưng hoạt động khi kết nối thủ công tín hiệu

Điều này làm việc khi tôi sử dụng PyGTK. Tôi đang chuyển sang PyGObject ngay bây giờ .. và có vẻ như kỹ thuật này sẽ hoạt động chỉ nếu tôi kết nối theo cách thủ công với tín hiệu phản hồi thay vì sử dụng Gtk.Builder.connect_signals().

Nhưng đừng dùng từ ngữ của tôi cho nó. Dưới đây là ví dụ tối thiểu về vấn đề của tôi:

from gi.repository import Gtk 

xml = """<interface> 
    <object class="GtkDialog" id="dialog1"> 
    <signal name="response" handler="on_response"/> 
    <child internal-child="vbox"> 
     <object class="GtkBox" id="dialog-vbox1"> 
     <child internal-child="action_area"> 
      <object class="GtkButtonBox" id="dialog-action_area1"> 
      <child> 
       <object class="GtkButton" id="button1"> 
       <property name="label">Don't Close Dialog</property> 
       <property name="visible">True</property> 
       </object> 
      </child> 
      <child> 
       <object class="GtkButton" id="button2"> 
       <property name="label">Close Dialog</property> 
       <property name="visible">True</property> 
       </object> 
      </child> 
      </object> 
     </child> 
     </object> 
    </child> 
    <action-widgets> 
     <action-widget response="0">button1</action-widget> 
     <action-widget response="-6">button2</action-widget> 
    </action-widgets> 
    </object> 
</interface> 
""" 

def on_button_clicked(widget): 
    d = DummyDialog() 
    d.dialog1.run() 
    d.dialog1.destroy() 

class DummyDialog: 
    def __init__(self): 
     self.builder = Gtk.Builder() 
     self.builder.add_from_string(xml) 
     self.dialog1 = self.builder.get_object('dialog1') 
     self.builder.connect_signals(self) 

    def on_response(self, widget, response, data=None): 
     print 'response:', response 
     if response >= 0: 
      widget.emit_stop_by_name('response') 

w = Gtk.Window() 
w.connect('destroy', Gtk.main_quit) 
b = Gtk.Button('Open Dialog') 
b.connect('clicked', on_button_clicked) 
w.add(b) 

w.show_all() 

Gtk.main() 

Khi bạn chạy ứng dụng này, bạn sẽ có cửa sổ với một nút. Khi bạn nhấp vào nút đó, một hộp thoại bật lên với hai nút, một nút có nhãn "Không đóng hộp thoại" và một hộp có nhãn "Hộp thoại đóng". Khi chạy mã trên, cả hai nút sẽ đóng hộp thoại.

Nhưng nếu bạn thay đổi từ việc sử dụng Gtk.Builder.connect_signals() tự kết nối tín hiệu bằng cách thay thế

 self.builder.connect_signals(self) 

với

 self.dialog1.connect('response', self.on_response) 

sau đó nó bắt đầu làm việc như thiết kế ("Do not Đóng Dialog" nút doesn 't đóng hộp thoại).

Nhưng không nên hai dòng đó chính xác giống hệt nhau trong ngữ cảnh này? Có cách nào để tìm ra những gì khác nhau giữa hai kịch bản?

Tôi có thể nói các tín hiệu vẫn được kết nối trong cả hai trường hợp vì văn bản vẫn được in tới CLI từ DummyDialog.on_response. Nhưng có vẻ như phần widget.emit_stop_by_name('response') ngừng hoạt động khi tôi sử dụng GtkBuilder.

Thậm chí khó hiểu hơn là nếu bạn lấy mã chính xác này và chạy nó trên PyGTK (thay đổi from gi.repository import Gtk thành import gtk as Gtk), thì nó hoạt động chính xác trong cả hai trường hợp (sử dụng self.builder.connect_signals(self) hoặc self.dialog1.connect('response', self.on_response)).

Trả lời

2

Tôi sẽ làm điều đó một chút khác biệt. Tháo dialog1.destroy() trong nút bấm gọi lại và thay đổi on_response callback để:

def on_response(self, widget, response, data=None): 
     print 'response:', response 
     if response < 0: 
      self.dialog1.destroy() 
+0

Cảm ơn, mà có vẻ như một giải pháp thanh lịch hơn chỉ bằng tay kết nối tín hiệu mà không làm việc, vốn đã được giải pháp trước đây của tôi. Nhưng tôi vẫn còn lúng túng vì sao mã gốc của tôi không hoạt động. – dumbmatter

Các vấn đề liên quan