Hello folks,
are there any examples of scrollbar usage available? I have a hard time to grasp how to use them, and I can't find any examples in the documentation.
Thanks!
On Do, Dez 12, 2013 at 12:59:32 +0100, Josef Wolf wrote:
are there any examples of scrollbar usage available? I have a hard time to grasp how to use them, and I can't find any examples in the documentation.
With this code:
(defun test-scrolled-frame () (with-ltk (:debug 3) (let* ((root (make-instance 'frame)) (scrolled (make-instance 'scrolled-frame :master root)) (quit-button (make-instance 'button :master root :text "Quit" :command (lambda () (setf *exit-mainloop* t)))))
(pack root :side :top) (pack scrolled :side :top) (pack quit-button :side :top)
(dolist (number '(1 2 3 4 5 6 7 8 9)) (let ((btn (make-instance 'button :master scrolled :text number :command (lambda () (format t "~a~%" number))))) (pack btn :side :top :anchor :w))))
(do-msg "huhu")))
I get an empty root window and the wish process hangs eating CPU.
If I change the code to use FRAME instead of SCROLLED-FRAME, the code works fine (but obviously without a scrollbar)
Any suggestions?
On 18:39 Thu 12 Dec , Josef Wolf wrote:
On Do, Dez 12, 2013 at 12:59:32 +0100, Josef Wolf wrote:
are there any examples of scrollbar usage available? I have a hard time to grasp how to use them, and I can't find any examples in the documentation.
With this code: ...
I haven't had much success with the wrapper classes for scrolled widgets, so I do it manually. For a more full treatment, see the tk documentation, but here's enough to get you started:
;First make a textbox and a scrollbar to go with it: (let ((tb (make-instance 'text :width 78 :height 20)) (tbsb (make-instance 'scrollbar :orientation :vertical))) ;Now put them where you want them; I'm using pack as it's the least code: (pack tb :side :left) (pack tbsb :side :left :fill :y) ;Now you need to tell the two widgets about each other (configure tbsb "command" (format nil "~a yview" (widget-path tb))) (configure tb :yscrollcommand (format nil "~a set" (widget-path tbsb))))
-Jason
On Do, Dez 12, 2013 at 12:27:59 -0800, Jason Miller wrote:
;First make a textbox and a scrollbar to go with it: (let ((tb (make-instance 'text :width 78 :height 20)) (tbsb (make-instance 'scrollbar :orientation :vertical))) ;Now put them where you want them; I'm using pack as it's the least code: (pack tb :side :left) (pack tbsb :side :left :fill :y) ;Now you need to tell the two widgets about each other (configure tbsb "command" (format nil "~a yview" (widget-path tb))) (configure tb :yscrollcommand (format nil "~a set" (widget-path tbsb))))
Thanks for the hint, Jason! But I am still struggling.
Your example works fine. But it covers only a single text widget. I am trying to scroll a collection of widgets, like this:
(defun scrolltest () (with-ltk () (let* ((root (make-instance 'frame)) (button-list (make-instance 'listbox :master root)) (scrollbar (make-instance 'scrollbar :master root :orientation :vertical)) (quit-button (make-instance 'button :master root :text "Quit" :command (lambda () (setf *exit-mainloop* t)))))
(pack root :side :top) (pack quit-button :side :bottom :pady 10) (pack button-list :side :left) (pack scrollbar :side :left :expand t :fill :y)
(configure scrollbar "command" (format nil "~a yview" (widget-path button-list)))
(configure button-list :yscrollcommand (format nil "~a set" (widget-path scrollbar)))
(dolist (button-number '(1 2 3 4 5 6 7 8 9 0)) (let ((b (make-instance 'button :master button-list :text button-number :command (lambda () (format t "~a~%" button-number))))) (pack b :side :top :anchor :w))))))
The widgets simply don't seem to be connected :-(
I have also tried with a frame instead of a listbox, but frames don't seem to support the yscrollcommand.
Am Fri, 13 Dec 2013 00:13:27 +0100 schrieb Josef Wolf jw@raven.inka.de:
On Do, Dez 12, 2013 at 12:27:59 -0800, Jason Miller wrote:
;First make a textbox and a scrollbar to go with it: (let ((tb (make-instance 'text :width 78 :height 20)) (tbsb (make-instance 'scrollbar :orientation :vertical))) ;Now put them where you want them; I'm using pack as it's the least code: (pack tb :side :left) (pack tbsb :side :left :fill :y) ;Now you need to tell the two widgets about each other (configure tbsb "command" (format nil "~a yview" (widget-path tb))) (configure tb :yscrollcommand (format nil "~a set" (widget-path tbsb))))
Thanks for the hint, Jason! But I am still struggling.
Your example works fine. But it covers only a single text widget. I am trying to scroll a collection of widgets, like this:
(defun scrolltest () (with-ltk () (let* ((root (make-instance 'frame)) (button-list (make-instance 'listbox :master root)) (scrollbar (make-instance 'scrollbar :master root :orientation :vertical)) (quit-button (make-instance 'button :master root :text "Quit" :command (lambda () (setf *exit-mainloop* t)))))
(pack root :side :top) (pack quit-button :side :bottom :pady 10) (pack button-list :side :left) (pack scrollbar :side :left :expand t :fill :y) (configure scrollbar "command" (format nil "~a yview" (widget-path button-list))) (configure button-list :yscrollcommand (format nil "~a set" (widget-path scrollbar))) (dolist (button-number '(1 2 3 4 5 6 7 8 9 0)) (let ((b (make-instance 'button :master button-list :text button-number :command (lambda () (format t "~a~%"
button-number))))) (pack b :side :top :anchor :w))))))
The widgets simply don't seem to be connected :-(
I have also tried with a frame instead of a listbox, but frames don't seem to support the yscrollcommand.
The Tcl/Tk code to scroll multiple wigets by a single scrollbar is:
# called by the widget proc yset {args} { eval [linsert $args 0 .f.sb set] yview moveto [lindex [.f.sb get] 0] }
# called by the scroll bar proc yview {args} { eval [linsert $args 0 .f.lb1 yview] eval [linsert $args 0 .f.lb2 yview] }
See the Tcl/Tk wiki "multi scrolling" http://wiki.tcl.tk/9254
But it still must be fiddled out how this works with LTK...
- edgar
On December 12, 2013 3:13:27 PM PST, Josef Wolf wrote:
On Do, Dez 12, 2013 at 12:27:59 -0800, Jason Miller wrote:
;First make a textbox and a scrollbar to go with it: (let ((tb (make-instance 'text :width 78 :height 20)) (tbsb (make-instance 'scrollbar :orientation :vertical))) ;Now put them where you want them; I'm using pack as it's the least
code:
(pack tb :side :left)
...
Thanks for the hint, Jason! But I am still struggling.
Your example works fine. But it covers only a single text widget. I am trying to scroll a collection of widgets...
Well, strangely enough, tk doesn't have this as a widget. There are variouls hacks to get it, and it looks like scrolled-frame implements it. However, when setting the master of widgets that go in it, you'll need to use the INTERIOR accessor like so:
(ltk:with-ltk () (let ((sf (make-instance 'ltk:scrolled-frame))) (ltk:pack sf) (loop for i from 1 to 20 for label = (make-instance 'ltk:label :master (ltk:interior sf) :text "Hello, World!") do (ltk:pack label))))
HTH, Jason
On Do, Dez 12, 2013 at 04:30:47 -0800, Jason Miller wrote:
Your example works fine. But it covers only a single text widget. I am trying to scroll a collection of widgets...
Well, strangely enough, tk doesn't have this as a widget. There are variouls hacks to get it, and it looks like scrolled-frame implements it. However, when setting the master of widgets that go in it, you'll need to use the INTERIOR accessor like so:
(ltk:with-ltk () (let ((sf (make-instance 'ltk:scrolled-frame))) (ltk:pack sf) (loop for i from 1 to 20 for label = (make-instance 'ltk:label :master (ltk:interior sf) :text "Hello, World!") do (ltk:pack label))))
This works great! Thanks Jason!
What is this INTERIOR thing? I've never seen such a thing in Perl/Tk. And the Tk doc's seem to suggest every non-mainwindow is an interior window. But this is about windows, not widgets.
There seems to be still one problem, though: When the root window is resized, the size of the scrolled-frame is not adopted. :expand t :fill :both don't seem to have an effect. The scrolled-frame seems to have a maximum size. Increasing this with the :height and :wide options don't seem to have an effect.
Here's the current code:
(with-ltk () (let* ((root (make-instance 'frame)) (branches (make-instance 'scrolled-frame :master root :height 1000 :width 1000)) (quit-button (make-instance 'button :master root :text "Quit" :command (lambda () (setf *exit-mainloop* t))))) (pack root :side :top) (pack branches :side :top :expand t :fill :both) (pack quit-button :side :top :pady 10)
(loop for i from 1 to 20 for label = (make-instance 'ltk:label :master (ltk:interior branches) :text (format nil "Hello, World ~d!" i)) do (ltk:pack label))
(bind root "<KeyPress-q>" (lambda (ev) (declare (ignore ev)) (exit-wish)))
(do-msg "huhu")))
On Friday 13 December 2013 08:10, Josef Wolf wrote:
There seems to be still one problem, though: When the root window is resized, the size of the scrolled-frame is not adopted. :expand t :fill :both don't seem to have an effect. The scrolled-frame seems to have a maximum size. Increasing this with the :height and :wide options don't seem to have an effect.
Here's the current code:
[...]
(pack root :side :top) (pack branches :side :top :expand t :fill :both)
Can you add :expand t :fill :both to the outer frame too?
Am Fri, 13 Dec 2013 00:13:27 +0100 schrieb Josef Wolf jw@raven.inka.de:
On Do, Dez 12, 2013 at 12:27:59 -0800, Jason Miller wrote:
;First make a textbox and a scrollbar to go with it: (let ((tb (make-instance 'text :width 78 :height 20)) (tbsb (make-instance 'scrollbar :orientation :vertical))) ;Now put them where you want them; I'm using pack as it's the least code: (pack tb :side :left) (pack tbsb :side :left :fill :y) ;Now you need to tell the two widgets about each other (configure tbsb "command" (format nil "~a yview" (widget-path tb))) (configure tb :yscrollcommand (format nil "~a set" (widget-path tbsb))))
Thanks for the hint, Jason! But I am still struggling.
Your example works fine. But it covers only a single text widget. I am trying to scroll a collection of widgets, like this:
(defun scrolltest () (with-ltk () (let* ((root (make-instance 'frame)) (button-list (make-instance 'listbox :master root)) (scrollbar (make-instance 'scrollbar :master root :orientation :vertical)) (quit-button (make-instance 'button :master root :text "Quit" :command (lambda () (setf *exit-mainloop* t)))))
(pack root :side :top) (pack quit-button :side :bottom :pady 10) (pack button-list :side :left) (pack scrollbar :side :left :expand t :fill :y) (configure scrollbar "command" (format nil "~a yview" (widget-path button-list))) (configure button-list :yscrollcommand (format nil "~a set" (widget-path scrollbar))) (dolist (button-number '(1 2 3 4 5 6 7 8 9 0)) (let ((b (make-instance 'button :master button-list :text button-number :command (lambda () (format t "~a~%"
button-number))))) (pack b :side :top :anchor :w))))))
The widgets simply don't seem to be connected :-(
I have also tried with a frame instead of a listbox, but frames don't seem to support the yscrollcommand.
After having a closer look at your code it appears to me that this is pretty much nonsense what you're trying there.
A listbox widget is meant to manage _text_ items that are displayed as a vertical list inside the widget.
A listbox widget is *not* meant to contain buttons. A listbox widget *cannot* scroll buttons.
What exactly are you trying to achive with this code?
Probably we can find a different solution, but I haven't understood what exactly is the desired purpose.
- edgar
On Fr, Dez 13, 2013 at 01:31:10 +0100, edgar wrote:
After having a closer look at your code it appears to me that this is pretty much nonsense what you're trying there.
Well, if you try about everything and nothing works, eventually you arrive at a point where you even try nonsense :-)
A listbox widget is meant to manage _text_ items that are displayed as a vertical list inside the widget.
Originally, I had a frame with a load of widgets. But as I wrote in my previous mail, the frame don't seem to support the yscrollcommand option.
Then I tried scrolled-frame, but this just hangs.
What exactly are you trying to achive with this code?
I have a frame of widgets, which are created dynamically (branches and files of a git repository), so chances are they won't fit on the screen. So I tried to scroll the frame, but the frame won't support the yscrollcommand.
Am Fri, 13 Dec 2013 07:41:07 +0100 schrieb Josef Wolf jw@raven.inka.de:
On Fr, Dez 13, 2013 at 01:31:10 +0100, edgar wrote:
After having a closer look at your code it appears to me that this is pretty much nonsense what you're trying there.
Well, if you try about everything and nothing works, eventually you arrive at a point where you even try nonsense :-)
Yes ... I remember ... that's exactly how I learned Tcl/Tk :-)
A listbox widget is meant to manage _text_ items that are displayed as a vertical list inside the widget.
Originally, I had a frame with a load of widgets. But as I wrote in my previous mail, the frame don't seem to support the yscrollcommand option.
Then I tried scrolled-frame, but this just hangs.
What exactly are you trying to achive with this code?
I have a frame of widgets, which are created dynamically (branches and files of a git repository), so chances are they won't fit on the screen. So I tried to scroll the frame, but the frame won't support the yscrollcommand.
Hierarchical browsers containing text (like file names and git branches) together with nodes (e.g. little graphics symbols) that can be expanded and collapsed are usually implemented by text widgets and text markers.
An example how this works can be found in the book "Effective Tcl/Tk Programming" by Mark Harrison and Michael McLennan: http://www.amazon.com/Effective-Tcl-Tk-Programming-Programs/dp/0201634740
A picture how this looks like can be found here: http://incrtcl.sourceforge.net/itcl/mmc/full/catalog.gif
The text browser on the left side contains small black triangles to expanded and/or collapse the text under the headlines.
Is that what you want?
I have a copy of "Effective Tcl/Tk Programming" and we could try to re-implement the browser widget in LTK.
- edgar
On Fr, Dez 13, 2013 at 08:25:47 +0100, edgar wrote:
Am Fri, 13 Dec 2013 07:41:07 +0100 schrieb Josef Wolf jw@raven.inka.de:
Well, if you try about everything and nothing works, eventually you arrive at a point where you even try nonsense :-)
Yes ... I remember ... that's exactly how I learned Tcl/Tk :-)
:-)
Do I really need to learn tcl when I want to use ltk? =8-O
Hierarchical browsers containing text (like file names and git branches) together with nodes (e.g. little graphics symbols) that can be expanded and collapsed are usually implemented by text widgets and text markers.
An example how this works can be found in the book "Effective Tcl/Tk Programming" by Mark Harrison and Michael McLennan: http://www.amazon.com/Effective-Tcl-Tk-Programming-Programs/dp/0201634740
A picture how this looks like can be found here: http://incrtcl.sourceforge.net/itcl/mmc/full/catalog.gif
The text browser on the left side contains small black triangles to expanded and/or collapse the text under the headlines.
Is that what you want?
That's pretty close. Things that I need which might be missing in such a browser are:
- preview/rename/move/remove files within a branch (possibly modifying file hierarchy) - move files from one branch to another - rename branches - merge branches
I have a copy of "Effective Tcl/Tk Programming" and we could try to re-implement the browser widget in LTK.
That would be great!
Fri, 13 Dec 2013 11:12:15 +0100 Josef Wolf jw@raven.inka.de wrote:
Do I really need to learn tcl when I want to use ltk? =8-O
You do not necessarily *need* to learn Tcl/Tk to use LTK, but if you don't know what you are doing you are doomed to write shitty programs. That is true for every programming language.
A picture how this looks like can be found here: http://incrtcl.sourceforge.net/itcl/mmc/full/catalog.gif
The text browser on the left side contains small black triangles to expanded and/or collapse the text under the headlines.
Is that what you want?
That's pretty close. Things that I need which might be missing in such a browser are:
- preview/rename/move/remove files within a branch (possibly modifying file hierarchy)
- move files from one branch to another
- rename branches
- merge branches
Such things are provided by *no* GUI toolkit I know, so it will be your task to add this functionality e.g. by binding Lisp functions to mouse-clicks or other GUI events.
I have a copy of "Effective Tcl/Tk Programming" and we could try to re-implement the browser widget in LTK.
That would be great!
I just realized that Tcl/Tk 8.6 has a ttk::treeview widget
man page http://www.tcl.tk/man/tcl/TkCmd/ttk_treeview.htm examples http://wiki.tcl.tk/20065
LTK supports the ttk::treeview widget by:
#:treeview #:treeview-delete #:treeview-focus #:treeview-exists #:treeview-insert #:treeview-item #:treeview-column #:treeview-heading #:treeview-move #:scrolled-treeview #:treeview-get-selection #:treeview-identify #:treeview-identify-item #:treeview-set-selection
The advantage of using the ttk::treeview widget would be that the LTK classes and methods already exist, the advantage of porting the "Effective Tclk/Tk" browser would be that it can be easily extended, it is implemented in Tcl/Tk (not in C).
The disadvantage of the ttk::treeview widget would be that it doesn't exist in Tcl/Tk version before Tcl/Tk 8.6.
I already have downloaded the "Effective Tclk/Tk" code and will try to make a LTK megawidget out of it over the weekend, but I will promise nothing until the code really works...
- edgar
Sorry, I'm an idiot, most important link forgotten...
The Tcl/Tk code from the book "Effective Tcl/Tk Programming" can be found here:
http://sourceforge.net/projects/efftcl/
- edgar