是否有可能在第一次打开ttk :: combobox之前获得其下拉列表的内容?

时间:2019-07-03 13:29:36

标签: tcl tk ttk itcl

我创建一个仅显示组合框的遮罩。我想将某些元素涂成红色。

出于几个原因,我必须拥有一个给定的结构,因此我需要三个文件。第一个创建顶层,第二个创建遮罩,还有填充组合框的方法。第三档 包括创建和处理组合框的所有方法。

这是第一个文件

  

(vmHelmert2.tcl):


    #!/bin/sh
    #\
    exec vmwish "$0" ${1+"$@"}

    package require itcl
    auto_mkindex . vmCombobox2.itcl vmMaskHelmert2.itcl
    lappend auto_path /myPath

    namespace eval vmHelmert2 {
       variable helmert
    }

    proc vmHelmert2::grundmaske {} {

       set top [toplevel .top  -class Helmert]
       set frMain [frame $top.centrum]
       pack $frMain -expand 1 -fill both

       set helmertWidget [vmMaskHelmert2 #auto $frMain]
       set helmert(widget) [$helmertWidget getThis]

    }

    vmHelmert2::grundmaske

这是第二个文件

  

(vmMaskHelmert2.itcl)


    package require Itcl

    ::itcl::class vmMaskHelmert2 {

       public method getThis {}

       private method createMaskHelmert {w}
       private method setAnsatzList {liste}
       private method faerbeAnsatzListe {}

       private variable pfd
       private variable data


       constructor {w} {
          createMaskHelmert $w
          return $this
       }

        destructor {
          #puts "DESTRUCTOR wird jetzt gestartet."
       }
    }

    ::itcl::body vmMaskHelmert2::getThis {} {
       return $this
    }

    ::itcl::body vmMaskHelmert2::createMaskHelmert {w} {
       set pfd(frMain) [frame $w.frMain]
       pack $pfd(frMain) -anchor nw -expand 1 -fill both
       set pfd(c_ansatznr) [vmCombobox2 $pfd(frMain).c_ansatznr \
                                -state normal \
                                -width 15\
                                -justify right]
       pack $pfd(c_ansatznr) -side left
       [$pfd(c_ansatznr) component combobox] configure -postcommand "[itcl::code $this faerbeAnsatzListe]"

       set data(ansatzList) [list 1 0 2 1 3 1]

       setAnsatzList $data(ansatzList)

    }

    ::itcl::body vmMaskHelmert2::setAnsatzList {liste} {
       # Alle Inhalte vorher loeschen
       $pfd(c_ansatznr) delete entry 0 end
       $pfd(c_ansatznr) delete list 0 end
       foreach {einElement status} $liste {
          $pfd(c_ansatznr) insert list end $einElement
       }
       return
    }

    ::itcl::body vmMaskHelmert2::faerbeAnsatzListe {} {
       foreach {elem state} $data(ansatzList) {
          if { $state } {
    #            puts "TODO: Farbe Ansatz $elem verändern!!!"
                $pfd(c_ansatznr) itemconfigure $elem red
          }
       }
    }

这是组合框的最后一个文件

  

(vmCombobox2.itcl):


    package require Itcl
    package require Iwidgets
    itcl::class vmCombobox2 {
       inherit itk::Widget
       constructor {args} {}
       destructor {}

       public method insert {component index args}
       public method delete {component first {last {}}}
       public method itemconfigure {bez farbe}

       private variable popdown

       private method create {top}

       protected method _deleteList {first {last {}}}
    }

    itcl::body vmCombobox2::constructor {args} {
       ttk::style configure Combobox$this.TCombobox\
          -selectbackground #52719c\
          -borderwidth 1\
          -insertwidth 2\
          -selectforeground white\
          -fieldbackground white
       ttk::style map Combobox$this.TCombobox -background [list disabled #a3a3a3 readonly #a3a3a3]
       ttk::style map Combobox$this.TCombobox -foreground [list disabled #d9d9d9 readonly #d9d9d9]
       ttk::style map Combobox$this.TCombobox -arrowcolor [list disabled darkgrey readonly black]
       create $itk_interior
       itk_initialize {*}$args
       # wenn -values vor -textvariable steht wird die Variable nicht initialisiert deshalb:
       set idx [lsearch $args "-textvariable"]
       if {$idx != -1} {
          setVar [lindex [$itk_component(combobox) cget -values] end]
       }
    }

    itcl::body vmCombobox2::create {top} {
    #   puts "createCombobox"
       # Label
       itk_component add label {
          set label [label $top.label -anchor w]
          set label
       } {
          rename -font -labelfont labelFont Font
       }
       # Frame fuer highlightthickness
       itk_component add frame {
          set frame [frame $top.frame -highlightcolor black]
          set frame
       } {
       }   

       # combobox
       itk_component add combobox {
          set combobox [ttk::combobox $top.frame.combo -style Combobox$this.TCombobox]
          set combobox
       } {
          keep -textvariable -values -cursor -exportselection -justify -height -state -width -takefocus -postcommand\
             -invalidcommand -foreground
          rename -validate -validateart validateArt ValidateArt
       }

       grid $itk_component(label) -row 0 -column 0 -sticky ne 
       grid $itk_component(frame) -row 0 -column 1 -sticky ew
       pack $itk_component(combobox) -fill x -expand 1
       grid columnconfigure $top 1 -weight 1
       grid rowconfigure $top 0 -weight 1

       # aufgeklappte Liste
       set pd [ttk::combobox::PopdownWindow $itk_component(combobox)]
       set popdown $pd.f.l
    }

    itcl::body vmCombobox2::_deleteList {first {last {}}} {

        if {$last == {}} {
           set last $first
        }
        set valueList [$itk_component(combobox) cget -values]
        set newValuesList [lreplace $valueList $first $last]

        # remove the item if it is no longer in the list
        set text [$itk_component(combobox) get]
        if {$text != ""} {
           set index [lsearch -exact $newValuesList $text]
           if {$index == -1} {
              $itk_component(combobox) set ""
             }
        }   
        $itk_component(combobox) configure -values $newValuesList
        return
    }

    itcl::body vmCombobox2::delete {component first {last {}}} {
        switch -- $component {
             entry {
                if {$last == {}} {
                   #set last [expr {$first + 1}]
                   set last $first
                }
              set text [$itk_component(combobox) get]
              set newText [string replace $text $first $last]
              $itk_component(combobox) set $newText
             }
             list {
                _deleteList $first $last
             }
             default {
                error "falsches Combobox component \"$component\":\
                         zugelassen sind: entry or list."
             }
       }
    }

    itcl::body vmCombobox2::insert {component index args} {
       set nargs [llength $args]

       if {$nargs == 0} {
            error "Kein Einfuegestring fuer parameter \"string\" in function\"vmCombobox2::insert\""
       } 

       switch -- $component {
          list {
             if {$itk_option(-state) == "normal"} {
                set aktuell [$itk_component(combobox) cget -values]
                  if {[lsearch -exact $aktuell $args] != -1} {
                     return
                   }
                set neu [linsert $aktuell $index [join $args]]
                $itk_component(combobox) configure -values $neu
             }
          }
          default {error "Falsches vmCombobox2 component \"$component\": zugelassen be entry oder list."}
       }
    }

    itcl::body vmCombobox2::itemconfigure {bez farbe} {

       puts "content popdownListe >>[$popdown get 0 end]<<"
       # index des Elements in popDownListe
       set index [lsearch [$popdown get 0 end] $bez]
       try {
          $popdown itemconfigure $index -foreground red
       } on error {err errOpts} {
          puts "Error >>$err<<"
       } 
    }

在方法vmCombobox2::itemconfigure中,我放置了popDownList的内容。 If的{​​{1}}首次为popDownList,内容为空,且所有元素均未染成红色(

  

content popdownListe

。我收到错误

  

项目号“ -1”超出范围

(当然,popDownList为空)。如果我第二次打开它,元素2和3会按预期显示为红色。

在第一次打开弹出式列表之前,是否可以将内容填充到弹出式列表中?

2 个答案:

答案 0 :(得分:1)

一种可能的解决方案是在显示列表之后配置项目。 您需要这样做:

  • vmCombobox的新版本(签出svn)

    示例:

    !/ bin / sh

    \

    exec vmwish“ $ 0” $ {1 +“ $ @”}

    包装要求Itcl 软件包需要vmWidgets 软件包需要vmTclTools 顶级.t 框架.t.fr 打包.t.fr

    全局WMS 可变变量 设置cb1 [vmCombobox .t.fr.li \     -textvariable :: wms(capabilitiesAddr)\     -selection命令getV \     -textfont {helvetica 10粗体} \     -labelfont {helvetica 10粗体} \     值[列表1 2 3 33i 1000 7] \     -textvariable :: wms(var)\     -高度20 \     -验证所有\     -验证{valMass%P} \     -labeltext testcombobox \     ] 包装$ cb1

    $ cb1插入列表结尾jojo 设置pd [$ cb1 getPopdown] $ cb1 configure -postcallback [列出configureLB $ pd] proc configureLB {pd} {    foreach我[$ pd得到0结尾] {       #hier Items konfigurieren       放$ i    }    $ pd itemconfigure结束-前景红色 }

答案 1 :(得分:0)

为了说明,这里的答案意味着我在vmCombobox2.itcl和vmMaskHelmert2.itcl中所做的更改

  

vmMaskHelmert2.itcl

我在组合框中添加了一个新选项-postcallback,并在faerbeAnsatzListe中对其进行了配置。

:itcl::body vmMaskHelmert2::faerbeAnsatzListe {} {
   set listIndex [list ]
   foreach {elem state} $data(ansatzList) {
      if { $state } {
#         puts "TODO: Farbe Ansatz $elem verändern!!!"
          set values [$pfd(c_ansatznr) getValues]
          set index [lsearch $values $elem]
          lappend listIndex $index
      }
   }
   set pd [$pfd(c_ansatznr) getPopdown]
   $pfd(c_ansatznr) configure -postcallback [list configureLB $pd $listIndex]
}

getValues是一种方法,该方法在组合框中列出了列表的所有项目。

  

vmCombobox2.itcl

我在vmCombobox2.itcl中添加了回叫选项

itcl::class vmCombobox {
...
itk_option define -postcallback postCallback PostCallback ""
...
}

在构造函数中,我添加了以下几行:

itcl::body vmCombobox::constructor {args} {
...
if {$idx != -1} {
   setVar [lindex [$itk_component(combobox) cget -values] end]
}
...
set pd [ttk::combobox::PopdownWindow $itk_component(combobox)]
set oldTags [bindtags $pd]
set tagList [concat $oldTags "callBack$this"]
bind callBack$this <Map> [itcl::code $this popUpCallback]
bindtags $pd $tagList
bind $pd <Unmap> [::itcl::code $this clearAfterSelect]

我又添加了三个方法(我也在类中将它们声明为公共方法)

itcl::body vmCombobox::getPopdown {} {
   return $popdown
} 
itcl::body vmCombobox::popUpCallback {} {
   if {$itk_option(-postcallback) != ""} {
      eval $itk_option(-postcallback)
   }
}

::itcl::body vmCombobox::configureLB {pd listIndex} {
   foreach index $listIndex {
      $pd itemconfigure $index -foreground red
   }
}

对我来说,它起作用了,所做的更改使我可以为某些项目着色。