如何在pygtk中将gtk.CellRendererText()列作为密码类型(*)

时间:2013-11-14 07:13:45

标签: python python-2.7 treeview gtk pygtk

我在我的脚本中使用pygtk创建了TreeView()表。在那一列中,文本框是密码类型,如果我键入密码,它显示字符,但密码应该是机密的。所以我想,当我输入密码时,它显示我就像看不见( * )。

我的代码写在下面

    #   columns
    (
      COLUMN_EDITABLE,
      COLUMN_USER,
      COLUMN_PSW,
    ) = range(3)
    model = gtk.ListStore(
       gobject.TYPE_BOOLEAN,
       gobject.TYPE_STRING,
       gobject.TYPE_STRING,
    )
    treeview = gtk.TreeView(model)

    #Password column
    renderer = gtk.CellRendererText()
    renderer.set_property('cell-background', '#efefef')
    renderer.set_fixed_size(120,20)
    renderer.connect("edited", self.on_cell_edited, model)
    renderer.set_data("column", COLUMN_PSW)
    column = gtk.TreeViewColumn("Password", renderer, text=COLUMN_PSW,
                           editable=COLUMN_EDITABLE)
    treeview.append_column(column)

现在有人建议我解决这个问题,我做什么

提前致谢..

2 个答案:

答案 0 :(得分:1)

您需要连接到文本渲染器的editing-started信号,并在处理程序中将GtkEditable的visibility属性设置为False。为避免在用户完成编辑时显示密码,您应将text属性设置为固定字符串,并清除editing-started处理程序中可编辑的内容。

def on_cell_edited_started(self, cell, editable, path):
    editable.delete_text(0, -1)
    editable.set_visibility(False)

然后在__init__

self.renderer.set_property("text", "*****")
self.renderer.connect("editing-started", self.on_cell_editing_started)

<强>更新

我无法使用***后显示的文字重现您的问题。我修改了你的代码如下。当我点击编辑时,文本被清除,当我完成编辑后,它会回到***

回调:

def on_cell_editing_started(self,cell, editable, path):
    editable.delete_text(0,-1)
    editable.set_visibility(False)
def on_cell_edited(self, renderer, path, new_text, model):
    iter = model.get_iter(path)
    model.set_value(iter, COLUMN_PSW, new_text)

设置渲染器:

    # psw column
    self.renderer = gtk.CellRendererText()
    self.renderer.connect("editing-started", self.on_cell_editing_started)
    self.renderer.connect("edited", self.on_cell_edited, model)
    self.renderer.set_property("text", "***")
    column = gtk.TreeViewColumn("Password", self.renderer ,editable=COLUMN_EDITABLE)
    treeview.append_column(column)  
    sw.add(treeview)
    self.show_all()

其他所有内容与您分享的最新文件一样。我怀疑你以某种方式将渲染器的text属性设置为set_property,并且还为其绑定了一列。如果您仍有问题需要仔细阅读文档并仔细检查您的代码,以便了解每条线路的作用,我将在接下来的10天左右离线。

答案 1 :(得分:0)

以下是上述问题的答案,但使用的是语言c#。

我进行了一些调查,并在the gtkmm documentation page上找到了以下代码

void ExampleWindow::cellrenderer_validated_on_editing_started(
    Gtk::CellEditable* cell_editable, const Glib::ustring& /* path */)
{
   //Start editing with previously-entered (but invalid) text, 
   //if we are allowing the user to correct some invalid data. 
   if(m_validate_retry)
   {
      //This is the CellEditable inside the CellRenderer. 
      Gtk::CellEditable* celleditable_validated = cell_editable;

      //It's usually an Entry, at least for a CellRendererText:
      Gtk::Entry* pEntry = dynamic_cast<Gtk::Entry*>(celleditable_validated);
      if(pEntry)
      {
         pEntry->set_text(m_invalid_text_for_retry);
         m_validate_retry = false;
         m_invalid_text_for_retry.clear();
      }
   }
}

它声明可以将基础可编辑对象转换为gtk条目。使用此条目,您可以轻松地将可见性设置为false,将不可见的字符设置为“ *”。

所以要把所有东西放在一起:

  • 在初始化时将celltextrenderer设置为默认字符串“ ***”
  • 挂钩事件编辑已开始
    • 在处理程序内部将可编辑内容转换为gtk条目
    • 清除gtk条目
    • 将条目的可见性设置为false
    • 将不可见的字符设置为“ *”
  • 挂钩事件已编辑
    • 提取新值并存储。

在c#中的解决方案下方:

// INIT
_textRenderer = new CellRendererText();
_textRenderer.Editable = true;
_textRenderer.EditingStarted += TextEditingStarted;
_textRenderer.Edited += TextEdited;
_textRenderer.Text = "***";

private void TextEditingStarted(object o, EditingStartedArgs args)
{
  if (args.Editable is Entry entry)
  {
    entry.InvisibleChar = '*';
    entry.Visibility = false;
    entry.Text = string.Empty;
  }
}

private void TextEdited(object o, EditedArgs args)
{
   var s = args.NewText;
   Console.WriteLine($"Password is {s}");
}