0

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

由于几个原因,我必须持有一个给定的结构,所以我需要三个文件。第一个创建顶层,第二个创建掩码,还有填充组合框的方法。第三个文件包括创建和处理组合框的所有方法。

所以这是第一个文件

(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. IfpopDownListopened第一次,内容是空的,没有一个元素是红色的(

内容弹出列表

. 我得到了错误

项目编号“-1”超出范围

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

有没有办法在第一次打开之前将内容填充到弹出列表中?

4

2 回答 2

1

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

  • vmCombobox 的新版本(查看 svn)

    例子:

    !/bin/sh

    \

    执行 vmwish "$0" ${1+"$@"}

    包需要 Itcl 包需要 vmWidgets 包需要 vmTclTools 顶层 .t 框架 .t.fr 包 .t.fr

    全局 wms 变量 var set cb1 [vmCombobox .t.fr.li\ -textvariable ::wms(capabilitiesAddr)\ -selectioncommand getV\ -textfont {helvetica 10 粗体}\ -labelfont {helvetica 10 粗体}\ -values [list 1 2 3 33i 1000 7]\ -textvariable ::wms(var)\ -height 20\ -validate all\ -validate {valMass %P}\ -labeltext testcombobox\ ] 包 $cb1

    $cb1 insert list end jojo set pd [$cb1 getPopdown] $cb1 configure -postcallback [list configureLB $pd] proc configureLB {pd} { foreach i [$pd get 0 end] { # hier Items konfigurieren puts $i } $pd itemconfigure end -foreground red }

于 2019-07-05T08:19:48.183 回答
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 中添加了选项 postcallback

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
   }
}

对我来说它有效,通过更改我可以为某些项目着色。

于 2019-07-09T09:32:20.933 回答