PyGTK中的简单、通用且可重用的输入对话框

5 投票
3 回答
5058 浏览
提问于 2025-04-17 07:11

我在找一个简单的对话框,里面有个文本输入框,可以让用户输入一些内容。这个对话框应该容易使用,就像gtk.MessageDialog那样,同时也要灵活。

当然,有一些例子,但要么不够灵活,要么对我来说构建起来太复杂了。

我不喜欢重复造轮子……或者说对话框。

3 个回答

3

这是我根据之前的回答写的一个函数。它是一个函数而不是一个类,这意味着你可以用一行代码就能使用它。

def get_text(parent, message, default=''):
    """
    Display a dialog with a text entry.
    Returns the text, or None if canceled.
    """
    d = gtk.MessageDialog(parent,
                          gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                          gtk.MESSAGE_QUESTION,
                          gtk.BUTTONS_OK_CANCEL,
                          message)
    entry = gtk.Entry()
    entry.set_text(default)
    entry.show()
    d.vbox.pack_end(entry)
    entry.connect('activate', lambda _: d.response(gtk.RESPONSE_OK))
    d.set_default_response(gtk.RESPONSE_OK)

    r = d.run()
    text = entry.get_text().decode('utf8')
    d.destroy()
    if r == gtk.RESPONSE_OK:
        return text
    else:
        return None
4

在GTK+中没有现成的解决方案。你有两个选择:

  • 创建一个对话框,把输入框(Entry)和其他需要的内容放进去(我觉得这可能是最好的方法)
  • 获取消息对话框的内容区域,然后在里面添加一个输入框(Entry)。

大概可以这样做:

#!/usr/bin/env python

import gtk

messagedialog = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_OK, message_format="Hello")

action_area = messagedialog.get_content_area()

entry = gtk.Entry()
action_area.pack_start(entry)

messagedialog.show_all()
messagedialog.run()
messagedialog.destroy()

不过可能还需要进一步调整,才能让输入框显示得更好看。

11

根据我找到的一个例子(感谢Ardoris!),我做了一个对话框的子类……希望能对某些人有所帮助!

#!/usr/bin/env python
import gtk
class EntryDialog(gtk.MessageDialog):
    def __init__(self, *args, **kwargs):
        '''
        Creates a new EntryDialog. Takes all the arguments of the usual
        MessageDialog constructor plus one optional named argument 
        "default_value" to specify the initial contents of the entry.
        '''
        if 'default_value' in kwargs:
            default_value = kwargs['default_value']
            del kwargs['default_value']
        else:
            default_value = ''
        super(EntryDialog, self).__init__(*args, **kwargs)
        entry = gtk.Entry()        
        entry.set_text(str(default_value))
        entry.connect("activate", 
                      lambda ent, dlg, resp: dlg.response(resp), 
                      self, gtk.RESPONSE_OK)
        self.vbox.pack_end(entry, True, True, 0)
        self.vbox.show_all()
        self.entry = entry
    def set_value(self, text):
        self.entry.set_text(text)
    def run(self):
        result = super(EntryDialog, self).run()
        if result == gtk.RESPONSE_OK:
            text = self.entry.get_text()
        else:
            text = None
        return text

这个run()方法会返回用户在输入框中输入的文本,如果用户按下<Enter>键或者点击了“确定”按钮。如果用户点击了“取消”或者按下了<Esc>键,run()方法就会返回None

除此之外,这个对话框的表现应该和其他的gtk.MessageDialog实例一样。

也许这并不是非常通用,因为它假设你总是会有“确定”这个选项,但反正这在我99%的使用场景中都是我需要的。

撰写回答