🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Q&A

解決済

1回答

1291閲覧

Ruby/tkのBWidgetでマウスホイールスクロールしたい

akira_kano1101

総合スコア25

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

0グッド

0クリップ

投稿2021/01/11 07:12

編集2021/01/13 03:50

期待すること

Ruby/tkのBWidgetで

  • ScrolledWindow
  • ScrollableFrame

これらを使い、マウスホイールによる画面のスクロールを実現することです。

とりあえずスクロールバーだけは動作するようにはできた

以前、BWidgetを使うと画面をスクロールさせることができる方法を下記で質問し、知識のある方から教えてもらいました。

そのときの内容はこちらです。
https://teratail.com/questions/313028

ただ、このとき辿り着いたのは、スクロールバーをドラッグすることでスクロールができるというところまでです。

マウスホイールでスクロールしたくて試行錯誤

そこまでは良いのですが、現状ではマウスホイールでは動きません。やはり、マウスホイールで画面スクロールをさせたいという希望がその後出てきて、実現させたく思っています。

ちなみに、以下が、解決に至るまで回答をくださった方のコード(上記リンクより抜粋)です。

ruby

1require 'tk' 2require 'tkextlib/bwidget' 3 4root = TkRoot.new 5 6sw = Tk::BWidget::ScrolledWindow.new(root) 7sf = Tk::BWidget::ScrollableFrame.new(sw, constrainedwidth: true) 8sw.set_widget(sf) 9vf = sf.get_frame 10vf.configure(bg: :white, borderwidth: 1, relief: :groove) 11 1210.times do |i| 13 TkButton.new(vf, text: "button #{i}").pack 14 TkLabel.new(vf, text: "label #{i}").pack 15end 16 17sw.pack(fill: :both, expand: true) 18 19Tk.mainloop

これを元にコードを触ったり情報を調べたり試行錯誤していますが、なかなかマウスホイールによるスクロールがうまくいきません。

ご存知の方いらっしゃいましたら、大変恐縮ですがご教示いただけませんでしょうか。

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

別言語なので参考になるかわかりませんが、(ActiveTcl で動作確認)
マウスホイールイベントは <MouseWheel> で設定します。
画面のどこからでも有効にするには bind all を使います。rubyでは多分 bind_all
ホィールイベント内で Scrollable オブジェクトの yview/xview を呼び出してスクロール。

tcl

1## ScrollableFrame のサンプルコード 2 3 package require BWidget 4 # Make a frame scrollable 5 set sw [ScrolledWindow .sw] 6 pack $sw -fill both -expand true 7 set sf [ScrollableFrame $sw.sf] 8 $sw setwidget $sf 9 set uf [$sf getframe] 10 # Now fill the frame, resize the window to see the scrollbars in action 11 for { set i 0 } { $i < 20 } { incr i } { 12 for { set j 0 } { $j < 20 } { incr j } { 13 set nm [format "%s.b_%s_%s" $uf $i $j] 14 set b [button $nm -text "$i,$j" -command {puts "OK"}] 15 grid $b -row $i -column $j 16 } 17 } 18 19## 追加部分: マウスホイール・イベント ※ Shift+ホィールで横スクロール 20 21bind all <MouseWheel> { 22 $sf yview scroll [expr {-%D/120}] units 23} 24bind all <Shift-MouseWheel> { 25 $sf xview scroll [expr {-%D/120}] units 26}

設定方法(以下のどちらか)

  • tcl の eval を呼び出す。Tcl/Tk のウィジェットは文字列 (path-name) なので、

 bind all ~の文字列を tcl の eval (root.e ?) で評価する事でも設定できます。
注意点: $sf は ScrolledFrame の path-name, {} や %D の % は場合によってはエスケープ

  • ruby で <MouseWheel> イベントを設定する
    root.bind_all "<MouseWheel>", {|e| sf.xview("scroll", e.delta/120, "units")}

 ※ 動作未確認です。%D の値はイベントにより渡される delta (ホィールの上下の判別に使う)


ちなみに、Tkinter は Python の標準ライブラリで、
Python 側では BWidget 等は保守されてません。

ruby でライブラリをインストールしようとして失敗し、
Python/tkinterで同等のコードを書こうとして断念した結果 tcl になりました。

rubyのコードは回答というわけでは有りません。
そのままでは動かないと思うので、参考程度にしてください。

投稿2021/01/13 04:54

teamikl

総合スコア8738

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akira_kano1101

2021/01/20 09:45

ありがとうございます。動作成功させることができました。 具体的コードは ``` root.bind_all('MouseWheel', proc { |e| sf.yview(:scroll, -e.delta, :units)}) ``` です。 本当に助かりました。 また機会がありましたらよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問