2013-06-16 6 views
1

Я создаю программу в python с gtk как gui, используя поляну. В этой программе у меня есть несколько диалоговых окон сообщений. Это просто, если я просто создаю много диалогового окна сообщений для каждого случая, который у меня есть. Но можно ли просто создать диалог с одним сообщением и использовать его для разных случаев с другим текстом? На самом деле это просто. Мне просто нужно изменить основной текст и показать его. Но я не нахожу способ изменить основной текст here и here.Как изменить основной текст в gtk messagedialog в python?

Ниже приведен пример кода:

from gi.repository import Gtk 

def clicked1(widget): 
    response = dialog1.run() 
    if response == Gtk.ResponseType.OK: 
     print 'ok' 
    else: 
     print 'cancel' 
     dialog1.destroy() 

def clicked2(widget): 
    response = dialog2.run() 
    if response == Gtk.ResponseType.OK: 
     print 'ok' 
    else: 
     print 'cancel' 
     dialog2.destroy() 

def clicked3(widget): 
    response = dialog3.run() 
    if response == Gtk.ResponseType.OK: 
     print 'ok' 
    else: 
     print 'cancel' 
     dialog3.destroy() 

builder = Gtk.Builder() 
builder.add_from_file('gui.glade') 
dialog1 = builder.get_object('dialog1') 
dialog2 = builder.get_object('dialog2') 
dialog3 = builder.get_object('dialog3') 
builder.get_object('button1').connect('clicked', clicked1) 
builder.get_object('button2').connect('clicked', clicked2) 
builder.get_object('button3').connect('clicked', clicked3) 
builder.get_object('window1').show_all() 
Gtk.main() 

Я хочу изменить это быть что-то вроде этого

from gi.repository import Gtk 

def clicked1(widget): 
    **dialog.set_text(1)** 
    response = dialog.run() 
    if response == Gtk.ResponseType.OK: 
     print 'ok' 
    else: 
     print 'cancel' 
     dialog.destroy() 

def clicked2(widget): 
    **dialog.set_text(2)** 
    response = dialog.run() 
    if response == Gtk.ResponseType.OK: 
     print 'ok' 
    else: 
     print 'cancel' 
     dialog.destroy() 

def clicked3(widget): 
    **dialog.set_text(3)** 
    response = dialog.run() 
    if response == Gtk.ResponseType.OK: 
     print 'ok' 
    else: 
     print 'cancel' 
     dialog.destroy() 

builder = Gtk.Builder() 
builder.add_from_file('gui.glade') 
**dialog = builder.get_object('dialog')** 
builder.get_object('button1').connect('clicked', clicked1) 
builder.get_object('button2').connect('clicked', clicked2) 
builder.get_object('button3').connect('clicked', clicked3) 
builder.get_object('window1').show_all() 
Gtk.main() 

ответ

1

Кажется, что нет непосредственно способ обновить текст в gtk_message_dialog после инициализации, но поскольку диалоговое окно сообщений представляет собой комбинацию полей, меток, изображений и кнопок, так что это уродливый способ изменения/обновления первичного/вторичного текста в диалоговом окне сообщений,

labels = dialog_info.get_children()[0].get_children()[0].get_children()[1].get_children()

Полный исходный код этого примера здесь:

#!/usr/bin/env python3 

from gi.repository import Gtk 

class Handler: 
    def __init__(self, builder): 
     self.builder = builder 
     self.window = builder.get_object('window1') 

    def run(self): 
     self.window.show_all() 
     Gtk.main() 

    def on_app_exit(self, widget, event=None): 
     Gtk.main_quit() 

    def on_button_show_clicked(self, btn): 
     dialog_info = self.builder.get_object('messagedialog_info') 
     entry = self.builder.get_object('entry1') 
     labels = dialog_info.get_children()[0].get_children()[0].get_children()[1].get_children() 
     print(labels) 
     # labels[0] is the primary label. 
     # labels[1] is the seconary label. 
     labels[0].set_text(entry.get_text()) 

     response = dialog_info.run() 
     print('response: ', response) 
     dialog_info.hide() 


def main(): 
    builder = Gtk.Builder() 
    builder.add_from_file('example.glade') 
    handler = Handler(builder) 
    builder.connect_signals(handler) 
    handler.run() 

if __name__ == '__main__': 
    main() 

и файл поляну, 'example.glade':

<?xml version="1.0" encoding="UTF-8"?> 
<interface> 
    <!-- interface-requires gtk+ 3.0 --> 
    <object class="GtkMessageDialog" id="messagedialog_info"> 
    <property name="can_focus">False</property> 
    <property name="border_width">5</property> 
    <property name="type_hint">dialog</property> 
    <property name="skip_taskbar_hint">True</property> 
    <property name="buttons">close</property> 
    <property name="text" translatable="yes">hello text</property> 
    <property name="secondary_text" translatable="yes">hello secondary text.</property> 
    <child internal-child="vbox"> 
     <object class="GtkBox" id="messagedialog-vbox"> 
     <property name="can_focus">False</property> 
     <property name="orientation">vertical</property> 
     <property name="spacing">2</property> 
     <child internal-child="action_area"> 
      <object class="GtkButtonBox" id="messagedialog-action_area"> 
      <property name="can_focus">False</property> 
      <property name="layout_style">end</property> 
      <child> 
       <placeholder/> 
      </child> 
      <child> 
       <placeholder/> 
      </child> 
      </object> 
      <packing> 
      <property name="expand">False</property> 
      <property name="fill">True</property> 
      <property name="pack_type">end</property> 
      <property name="position">0</property> 
      </packing> 
     </child> 
     </object> 
    </child> 
    </object> 
    <object class="GtkWindow" id="window1"> 
    <property name="can_focus">False</property> 
    <property name="border_width">5</property> 
    <signal name="delete-event" handler="on_app_exit" swapped="no"/> 
    <child> 
     <object class="GtkBox" id="box1"> 
     <property name="visible">True</property> 
     <property name="can_focus">False</property> 
     <property name="valign">center</property> 
     <property name="spacing">5</property> 
     <child> 
      <object class="GtkEntry" id="entry1"> 
      <property name="visible">True</property> 
      <property name="can_focus">True</property> 
      <property name="invisible_char">●</property> 
      </object> 
      <packing> 
      <property name="expand">True</property> 
      <property name="fill">True</property> 
      <property name="position">0</property> 
      </packing> 
     </child> 
     <child> 
      <object class="GtkButton" id="button_show"> 
      <property name="label" translatable="yes">_Show</property> 
      <property name="use_action_appearance">False</property> 
      <property name="visible">True</property> 
      <property name="can_focus">True</property> 
      <property name="receives_default">True</property> 
      <property name="use_action_appearance">False</property> 
      <property name="use_underline">True</property> 
      <signal name="clicked" handler="on_button_show_clicked" swapped="no"/> 
      </object> 
      <packing> 
      <property name="expand">False</property> 
      <property name="fill">True</property> 
      <property name="position">1</property> 
      </packing> 
     </child> 
     </object> 
    </child> 
    </object> 
</interface> 
+0

Я думаю, что это хорошо, спасибо за помощь :) – user2435611

+0

Я нашел простой способ, используя 'gtk_message_dialog_get_message_area()', который возвращает поле, содержащее две метки. :) – LiuLang

+0

и как получить доступ к основной текстовой метке? – user2435611

2

В качестве альтернативы, мы можем просто написать некоторые обертывания функции gtk_message_dialog , и вот простой пример:

def info(text, text2=None): 
    dialog = Gtk.MessageDialog(None, 
      Gtk.DialogFlags.MODAL, 
      Gtk.MessageType.INFO, 
      Gtk.ButtonsType.OK, 
      text) 
    if text2 != None: 
     dialog.format_secondary_text(text2) 
    response = dialog.run() 
    dialog.destroy() 

Проблемы в том, что если в диалоговом окне сообщения не будет выделено родительское окно, оно будет отображаться в центре экрана, а не в центре программы. Чтобы решить эту проблему, мы можем поместить функцию info() в класс и установить параметр родительского окна.

Другие типы сообщений, такие как предупреждение, вопрос и ошибка, могут сделать то же самое.

И небольшая демонстрация:

#!/usr/bin/env python3 

from gi.repository import Gtk 

def info(text, text2=None): 
    dialog = Gtk.MessageDialog(None, 
      Gtk.DialogFlags.MODAL, 
      Gtk.MessageType.INFO, 
      Gtk.ButtonsType.OK, 
      text) 
    if text2 != None: 
     dialog.format_secondary_text(text2) 
    response = dialog.run() 
    dialog.destroy() 

def error(text, text2=None): 
    ''' 
    TODO 
    ''' 
    pass 

def main(): 
    win = Gtk.Window() 
    win.connect('delete-event', Gtk.main_quit) 
    win.show_all() 
    info('hello') 
    info('hello, primary text', 'hello secondary text') 

    Gtk.main() 

if __name__ == '__main__': 
    main() 

Widget Структура диалогового окна сообщения, как это: enter image description here

1

Может быть немного слишком поздно, но я искал то же самое, и я мог получить простой, но эффективный способ изменения первичных и вторичных текстов без вызова какого-либо готового метода GtkMessageDialog.

Я просто пытался понять, как было невозможно что-то легче изменить эти тексты, не вызывая предварительно созданные методы «set_markup» и «format_secondary_text». Даже если «format_secondary_text» работает как прелесть и де-факто меняет второй текст отлично, «set_markup» изменяет основной текст, но не так, как должен, потому что он не получает как заголовок в присутствии второго текста, я ожидал его становится полужирным, но ожидает некоторую разметку PANGO, в противном случае это всего лишь простой текст без жирного шрифта.

Тогда я открыл Idle только взглянуть на все методы, свойства и т.д., которые могут быть доступны для GtkMessageDialog и я нашел что-то, как я вставить его ниже:

import gi 
gi.require_version('Gtk', '3.0') 
from gi.repository import Gtk 
builder = Gtk.Builder() 
#any Glade file with at least 1 GtkMessageDialog 
builder.add_from_file("myFile.glade") 
#The ID of GtkMessageDialog in Glade 
myDialog = builder.get_object("GtkMessageDialog1") 

#Below I change primary and secondary texts before running the Dialog. 
myDialog.set_property("text","Hello World") 
myDialog.set_property("secondary_text","Here I go again.") 

myDialog.run() 
myDialog.hide() 

Просто обратите внимание, как я написал с использованием Python 2.7, но принцип должен быть таким же, как с Python 3.x.