1

我正在使用 glade 使用 gtk 作为 gui 在 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()
4

3 回答 3

3

也许有点太晚了,但我一直在寻找同样的东西,我可以获得一种简单而有效的方法来更改主要和次要文本,而无需调用任何 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 相同。

于 2017-03-29T22:33:33.773 回答
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()

和林间空地文件,'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">●&lt;/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>
于 2013-06-16T10:45:52.647 回答
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()

消息对话框的小部件结构如下: 在此处输入图像描述

于 2013-06-16T11:09:16.937 回答