Есть ли возможность получить содержимое всплывающего списка ttk :: combobox перед его первым открытием? - PullRequest
0 голосов
/ 03 июля 2019

Я создаю маску, которая показывает только поле со списком. Я хочу покрасить определенные элементы в красный.

По нескольким причинам я должен держать заданную структуру, поэтому мне нужны три файла для нее. Первый создает верхний уровень, во втором создается маска, а также есть методы для заполнения поля со списком. Третий файл включает все методы для создания и обработки комбинированного списка.

Итак, это первый файл

(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 popDownList - это opened в первый раз, содержимое пусто, и ни один из элементов не окрашен в красный цвет (

содержание popdownListe

. Я получил ошибку

номер позиции "-1" вне диапазона

(наверняка, popDownList пуст). Если я открою его во второй раз, элементы 2 и 3 будут окрашены в красный цвет, как и ожидалось.

Есть ли способ заполнить содержимое всплывающего списка до его первого открытия?

Ответы [ 2 ]

1 голос
/ 05 июля 2019

Одним из возможных решений будет настройка элементов после отображения списка.Для этого вам нужно:

  • новая версия vmCombobox (проверьте svn)

    Пример:

    ! / Bin / sh

    \

    exec vmwish "$ 0" $ {1 + "$ @"}

    пакет требует пакет Itcl требует пакет vmWidgets требует пакет vmTclTools для заполнения .t фрейма .t.fr пакет .t.fr

    глобальная переменная wms var set cb1 [vmCombobox .t.fr.li \ -textvariable :: wms (abilitiesAddr) \ -selectioncommand getV \ -textfont {helvetica 10 полужирный} \ -labelfont {helvetica 10 полужирный} \-values ​​[список 1 2 3 33i 1000 7] \ -textvariable :: wms (var) \ -height 20 \ -validate all \ -validate {valMass% P} \ -labeltext testcombobox \] пакет $ $ cb1

    $ cb1 конец списка вставки jojo set pd [$ cb1 getPopdown] $ cb1 configure -postcallback [list configureLB $ pd] proc configureLB {pd} {foreach i [$ pd get 0 end] {# hier Элементы, которые конфигурирует ставит $ i} $pd itemconfigure end -foreground red}

0 голосов
/ 09 июля 2019

Чтобы проиллюстрировать, что здесь подразумевалось под ответом, изменения, которые я внес в 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

Я добавил опцию postcallback в 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
   }
}

Для меня это сработало, с изменениями я могу раскрасить некоторые предметы.

...