如何在python中更改gtk messagedialog中的主要文本?

时间:2013-06-16 09:17:38

标签: python user-interface gtk messagedialog

我正在使用glade用gtk作为gui在python中创建程序。在那个程序中,我有几个消息对话框。如果我为每个案例制作许多消息对话框,这很简单。但是,是否可以只创建一个消息对话框并将其用于具有不同文本的不同情况?实际上这很简单。我只需要更改主要文本并显示它。但是,我找不到更改主要文字herehere的方法。

以下是示例代码:

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()

3 个答案:

答案 0 :(得分:2)

似乎没有直接的方法在初始化后刷新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()

和glade文件'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>

答案 1 :(得分: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()

消息对话框的小部件结构如下所示: enter image description here

答案 2 :(得分:2)

也许有点太晚了,但我一直在寻找相同的东西,我可以在不调用任何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相同。