从自定义对话框获取输入,包含输入框、确定和取消按钮 - Python/GTK3

0 投票
1 回答
3953 浏览
提问于 2025-04-18 18:08

在Python和gobject一起使用时,我遇到了很大的问题,无法获取用户的输入。

这是我的代码:

def get_network_pw(self, e):
        def okClicked(self):
            print(pwd.get_text())
            return pwd.get_text()
            pwDialog.destroy()

        def cancelClicked(self):
            print("nope!")
            pwDialog.hide()
            return None

        #Getting the about dialog from UI.glade
        pwDialog = self.builder.get_object("passwordDialog")
        okBtn = self.builder.get_object("pwdOkBtn")
        cancelBtn = self.builder.get_object("pwdCancelBtn")
        pwd = self.builder.get_object("userEntry")
        # Opening the about dialog.
        #okBtn.connect("clicked", okClicked)
        #cancelBtn.connect("clicked", cancelClicked)
        pwDialog.run()

我不知道哪里出错了?它就是不返回用户输入的文本。我还尝试了来自Python/Gtk3 : 如何将Gtk.Entry添加到Gtk.MessageDialog中?简单、灵活且可重复使用的输入对话框(有时称为输入对话框)在PyGTK中的代码,但都没有成功。

编辑

我在glade中制作了一个对话框。它包含一个GtkTextBox(userEntry)、一个确认按钮(pwdOkBtn)和一个取消按钮(pwdCancelBtn)。当用户点击确认时,理论上应该返回他们在文本框中输入的内容(比如,1234)。当他们点击取消时,应该返回None。然而,当他们点击确认时,它返回的是"",而点击取消时也返回""。我不知道我哪里出错了。

额外的代码尝试:

我还尝试了以下代码:

def get_network_pw(self, e):
        d = GetInputDialog(None, "Enter Password")
        dialog = d.run()
        if dialog is 1:
            print("OK")
        else:
            print("Nope!")
        d.hide()

获取输入对话框:

class GetInputDialog(Gtk.Dialog):
    def __init__(self, parent, title):
        Gtk.Dialog._init(self, title, parent)
        self.response = "Cancel"
        self.setupHeader()
        self.setupUI()

    def setupUI(self):

        wdg = self.get_content_area() #explained bellow

        self.txtSource = Gtk.Entry() #create a text entry
        wdg.add(self.txtSource)
        self.show_all() #show the dialog and all children

    def setupHeader(self, title="Get User Input"):
        hb = Gtk.HeaderBar()
        hb.props.show_close_button = True
        hb.props.title = title
        self.set_titlebar(hb)

        btnOk = Gtk.Button("OK")
        btnOk.connect("clicked", self.btnOkClicked)
        hb.pack_start(btnOk)

        btnCancel = Gtk.Button("Cancel")
        btnCancel.connect("clicked", self.btnCancelClicked)
        hb.pack_start(btnCancel)

    def btnOkClicked(self, e):
        self.response = "Ok" #set the response var
        dst = self.txtSource #get the entry with the url
        txt = dst.get_text()
        return 1

    def btnCancelClicked(self, e):
        self.response = "Cancel"
        return -1

1 个回答

1

我觉得你把事情搞得太复杂了。这个运行方法会返回在对话框中按下的按钮的ID:

  1. 不要那样使用 .hide().destroy() 方法,这两个方法是用在不同的情况下的。.destroy() 是用来销毁小部件的,所以除非你知道自己在做什么,不然不要调用它。

  2. .hide() 放在 .run() 之后。

  3. 获取 run() 的返回值,并在 Glade 中为对话框的按钮设置不同的 响应ID

相关的代码部分是:

def _btn_cb(self, widget, data=None):
    """
    Button callback
    """
    ret = self.dialog.run()
    self.dialog.hide()
    if ret == 0:
        self.label.set_text(
            self.entry.get_text()
        )

这个例子的完整代码在这里:

https://gist.github.com/carlos-jenkins/c27bf6d5d76723a4b415

额外提示: 如果你想检查某个条件来决定是否接受确定按钮(比如检查输入是否有效),可以在一个循环中执行 run(),检查按钮是否是取消,如果是就跳出循环;如果不是,就检查输入的有效性,如果有效就做点什么并跳出循环,否则继续:

def _btn_cb(self, widget, data=None):
    """
    Button callback
    """
    while True:
        ret = self.dialog.run()
        if ret == -1:  # Cancel
            break

        try:
            entry = int(self.entry.get_text())
            self.label.set_text(str(entry))
            break
        except ValueError:
            # Show in an error dialog or whatever
            print('Input is not an integer!')

    self.dialog.hide()

撰写回答