2017-03-07 68 views
0

我想創建一個使用TCL/TK的表,並且在不使用Tktable小部件的情況下構建它。一次選擇多個TCL/TK文本小部件

我使用的是帆布打造從根本上使用的方法中提供的表格:

simple Tktable

我有自定義的一大堆這(到目前爲止)我覺得是比較容易,如果我建在畫布中的表格,因此我使用這種方法而不是Tktable。

我的表格將充滿只讀文本小部件,可編輯文本小部件和一些下拉菜單。

這裏是我的問題:

1)我怎麼能允許用戶同時選擇多個文本控件和檢索的選擇?如說,用戶選擇一整行/列等

請參閱下面的簡化的代碼:

package require Tk 

proc makeWindow {} { 
    set toplevelWindow .gui 
    destroy $toplevelWindow 

    ## Make the toplevel window 
    toplevel $toplevelWindow 
    wm title $toplevelWindow "Test case 1" 
    wm minsize $toplevelWindow 200 200 
    set pathName $toplevelWindow.testMultiSelection 

    ## Create the canvas where I build the table 
    destroy $pathName 
    frame $pathName 

    set col 0 
    for {set i 0} {$i < 4} {incr i} { 
     set w "$pathName\_$i" 
     destroy $w 
     text $w -width 9 -height 1 -state normal 
     $w insert end $i 
     $w configure -state disabled 
     grid $w -row $i -column $col -sticky ew 
    } 
    grid config $toplevelWindow.testMultiSelection -column 0 -row 0 -sticky w 
} 

makeWindow 

在上述例子中,我期望選擇幾號(基本上類似的CTRL + select),並以某種方式將選擇存儲在某處並檢索它們以供以後使用。

請讓我知道,如果上述精簡的測試案例不明確。

編輯1

忘了補充一點,我知道如何使用selection get命令檢索單個文本組件的選擇。

回答

1

默認情況下,選項一次僅限於一個小部件。如果您關閉每個窗口小部件的窗口小部件導出選擇(配置-exportselection 0),那麼您可以接管其管理。但是,除非窗口小部件具有焦點(由於平臺GUI規則),否則某些平臺也不會顯示選擇,因此您可能還需要管理文本標記以應用選擇的外觀。 (該sel標籤的選擇;它是專門管理,但是你可以很輕鬆地複製它的外觀。)

記住,你可以同時嵌入畫布和文本部件(內部部件如果子控件有名稱,使他們的孩子的容器)。子目錄和/或項目類型window是您在那裏尋找的路線。

另一件大事是管理剪貼板。你需要明確地說明這一點。通常的命令是clipboard,雖然也可以使用selection命令(它可以訪問剪貼板/選擇機制的底層部分;剪貼板是CLIPBOARD選擇)。

瞭解這一點,你正在做的事很複雜,可能需要相當多的時間和精力。問自己你的項目是否真的在這個複雜程度上是合理的。

+0

謝謝你的解釋。當我開始這個項目時,我認爲我被誤導了。我現在正在探索其他可用於開發「Excel」的其他大型小部件,如儀表板(迄今爲止的Tktable和tablelist)。提到的小部件在處理我的需求方面要好得多。 – sanjay

1

這個想法的要點是使用文本標記來標記選定的文本,以便您不僅可以顯示所選文本,還可以將該文本標記爲「已選中」。然後,您的複製操作僅遍歷所有文本小部件,並獲取內容(如果它擁有「已選」標籤)。您可以通過刪除標記或按照以下操作取消選擇文本,而按鈕命令會用自己的撤消命令替換它。

所以流程是點擊列按鈕,該列中的所有文本小部件都將其內容標記爲選中(選定的文本是白色背景&黑色前景,因此看起來被選中)點擊彈出式菜單或菜單按鈕訪問所有選擇的項目並對內容執行操作,然後單擊列按鈕以取消選擇該列。所有選定的文本小部件都會移除選定的標籤,並恢復文本的默認外觀。

假設您單擊列的頂部(我假設它是一個按鈕),並且您知道該列中的文本小部件,您可以使用標記標記每個文本小部件中的文本以指示它被選中。然後複製,您可以遍歷所有文本小部件,並拉動標記的每個文本小部件中的內容。取消選擇迭代所有文本小部件並取消標記內容。在下面的代碼假設我有以下功能:getAllTextWindowPaths - 給我的畫布中的所有textwidgets列表,getAllTextPathsInColumn colnumber - 給我列在畫布中列$ colnumber中的所有textwidgets。

# configure tags for all your text windows 

foreach t [ getAllTextWindowPaths ] { 
    $t tag configure selected -background white -foreground black 
} 
# configure the column select button 
button .canvas.button.column1 -text {1} -command [ list clickColumn      .canvas.button.column1 1 ] 

proc selectText { textpath { select 1 } } { 
    if { $select == 1 } { 
    $textpath tag add 1.0 end selected 
    } else { 
    $textpath tag remove 1.0 end selected 
    } 
} 

proc clickColumn { colpath colnum } { 
    # now call this click handler for for your column of textwidgets 
    # you can make same for a row 

    foreach t [getTextPathsInColumn $colnum ] { 
    selectText $t 1 
    } 
    $colpath configure -command [list unclickColumn $colpath $colnum ] 
} 
proc unclickColumn { colpath colnum } { 
    # now call this click handler for for your column of textwidgets 
    # you can make same for a row 

    foreach t [getTextPathsInColumn $colnum ] { 
    selectText $t 1 
    } 
    $colpath configure -command [list clickColumn $colpath $colnum ] 
} 

proc getSelectedContents { } { 
    # im adding to a list all the seleted contents but you can arrange 
    # it anyway you want 
    set retval {} 
    foreach t [getAllTextWindowPaths ] { 
     if { "selected" in [$t tag names 1.0 ] } { 
      lappend retval [ $t get 1.0 end ] 
     } 
    } 
    # optional call selectText $t 0 here foreach selected widget 
    # to clear selection or handle the column click handler again 
    return $retval 
} 
+0

這是解決問題的好方法。我試了兩個文本小部件,它似乎工作。無論如何,我仍然認爲這對於我的儀表板/表應用程序來說是相當複雜的事情。 megawidget表格似乎正在處理我的要求。 – sanjay