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

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

詳細はこちら
Ruby

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

Q&A

解決済

1回答

1519閲覧

Ruby/tkでTkScrollboxにImageやLabelを含むFrameを追加したい

akira_kano1101

総合スコア25

Ruby

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

0グッド

0クリップ

投稿2020/12/29 11:07

こんにちは。

RubyでGUIのプログラムを組んでいて、この件についてググっても情報が少なくなかなか良い答えが見つけられなくてわからなかったので、こちらに質問させていただきました。

開発環境

  • macOS 11.1 Big Sur
  • ruby2.7.2
  • tk_version 8.6

問題の前提

RubyでGUI上で動くプログラムを、Ruby/tkを使って組もうとしています。

次は、ネットの情報を拝借してきて文字列だけをScrollboxに追加して、単にスクロールの動作ができることを確認したものです。

ruby

1require 'tk' 2 3parent = TkRoot.new 4 5list = TkScrollbox.new(parent).pack(side: 'top', fill: 'both') 6('A'..'Z').each_with_index{|c, i| list.insert(:end, c * (i + 1))} 7 8Tk.mainloop

期待する結果

これを文字列ではなく、ウィジェットやウィジェットをいくつか含めてTkFrameなどで行ごとにしたものを、リストさせたいです。

具体的には、TkScrollboxに挿入される行ごとに、TkLabelやTkImageを含むTkFrameを表示させたいです。
つまり一行に文字列画像を混在させて、それを複数行にしたときにスクロールして上から下まで見られるようにしたいです。

伝わりにくいかもしれないので、もう一度言い換えると、TkLabelやTkButton、TkPhotoImageといったいくつかの要素を横並びにまとめたTkFrameを、一行一行縦に並べて画面を縦にスクロールして、アイテムをまとめて目で見て確認できるように扱いたいと考えています。

試したこと

試したコードがこちらです。

ruby

1require 'tk' 2 3parent = TkRoot.new 4 5list = TkScrollbox.new(parent).pack(side: 'top', fill: 'both') 6label = TkLabel.new(parent, text: 'SAMPLE') 726.times{ list.insert(:end, label)} 8 9p label 10 11Tk.mainloop

この結果、ウィンドウ画面は表示されました。相変わらずスクロールも、期待通りに動いてくれます。

しかし表示されているものが、望む結果ではありません。

立ち上がったウィンドウでは、次のように表示されました。(これらはスクロールはできますし、項目も追加されています。)

.w00003 .w00003 .w00003 .w00003 .w00003 (中略) .w00003

そして、ターミナルにはこう表示されます。

#<Tk::Label:0x00007fd88c91e788 @path=".w00003">

おそらく、@pathの値が何らかの形で文字列に変換され、Scrollboxに代入されているのだと思います。

しかし、これでは意味がありません。

私が表示させたいのは、期待する文字列を含むラベルや画像です。

その他

調べてみたところTkFrameにはスクロールバーを設定できないようなのでTkCanvasにTkFrameを配置してみてTkCanvasにスクロールさせるのが良いと言っているところもありました。

ただ、これもわかる限り試してみましたが、プログラムが良くないのか、思うようにならず困っています。

もしかして、TkCanvasのやり方なら、可能なのでしょうか。

それとも、そもそもこういったことは実現ができないのでしょうか?

さいごに

どうか、お詳しい方、ご教示いただけませんでしょうか。

よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

Ruby/Tk
6年ぐらい前に書いたコードを引っ張り出して見てみました。
今の私はほとんどRuby/Tkを忘れてしまいましたが、当時の私によると、BWidgetを使って

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

とやっていました。まあわざわざBWidget引っ張ってきたということは、標準のウィジェットツールではやりにくかったということなんでしょうね。

今の私はRuby/Tkを忘れてしまったのであまり回答できませんが、当時の私はBWidgetを使うのがベストだと考えたようです。一応ご参考まで。

投稿2020/12/29 11:45

編集2020/12/29 11:52
kojix2

総合スコア49

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

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

akira_kano1101

2020/12/29 13:18

お返事ありがとうございます。 わかりました。BWidgetでできるのですね! 今ダウンロードしたBWidgetを解凍して /usr/local_lib/tcl に置いて、ターミナルで % tclsh % lappend auto_path /usr/local/lib/tcl % package require BWidget とすると 1.9.14 が表示されるのでダウンロードしたBWidget自体は動いていそうです。 ただ、今の上のようにしないとBWidgetを読み込めません。 tclshをexitするたびにその中で毎回lappendしないとダメなようで、そうするとグローバル変数auto_pathの設定が環境変数からうまくプログラム内に読み込めないため、教えていただいたコードを動かすことができませんでした。 https://wiki.tcl-lang.org/page/Getting+started+with+BWidgethttps://bitwalk.blogspot.com/2008/11/tcloo-tcl_29.html を参考に探しているのですが、わかりませんでした。 まだ手探りの最中ではありますが、もしかすると拡張子「.tcl」を使うプログラムを書く必要あるのでしょうか? もう少し、動くところまで頑張りたいので、わかる範囲で良いのでお助け願えませんか? よろしくお願いします。
kojix2

2020/12/29 13:52

ちょっとmac環境が手元にないのでちょっとわかりません。 しかし所定のtcltkのディレクトリにbwidgetを突っ込むだけでいいような気もしたので、tcl/tkのディレクトリを探して、それらしい場所にBWidgetのファイルを突っ込むのが良い気がします。最近のMacはセキュリティが厳しいのダメかもしれませんが。 activestateから新しいtcltkをMacに入れて、teacupでbwidgetみたいなライブラリをゲットするという手もあるかも知れません。 ただ、個人的にはMacはTkの良さがもっとも薄れてしまう環境だと思います。Macで動かすことを考えるのなら、ムリにTkを使わない方が幸せになれるかも知れません…。
akira_kano1101

2020/12/30 02:03

お返事ありがとうございます。 activestateとteacupは少し調べてみました。 なかなか習得に時間がかかりそうです。もう少し時間をかけて見たいと思います。 MacはTkと相性が良くないんですか? 初めて知りました。 別のGUIならもっと使いやすいことがあるのでしょうか? さいごに、興味があるのでわかる範囲で結構ですので、Tk以外にもRubyで使えるおすすめのGUIがあれば教えていただきたいです。 もう少し自分でも頑張ってみます。 よろしくお願いします。
kojix2

2020/12/30 02:44 編集

いえいえ、私も凄い詳しいわけではないのですが、RubyでGUIをやる人はすごい応援しています! 私自身6年ぐらい前まではMacユーザーでした。Mac環境やLinux環境でTkが良くないのは、どうしてもネイティブのアプリに比べて見栄えが劣ることです。Macは綺麗なアプリが多いですから。 実用上は全く問題ありません! 私の記憶に間違いなければbwidgetは、単にBWidgetを正しくディレクトリに配置するだけで動くはずです。動かない場合は、`gem install tk` をやり直すと動くようになる場合もあるかも知れません。 RubyでGUI、万能な選択肢はないのが現状です。作りたいツールによって使うべき選択肢は違うと思いますが、Ruby/Tkも決して悪くはないと思います。 私なら、ある程度大きなものを作るなら、 * https://github.com/ruby-gnome/ruby-gnome/tree/master/gtk3 * 【Ruby】10分でGladeを使って作るRuby/GTK3 GUIアプリ https://qiita.com/kojix2/items/d9da8e08757dcc6b1a7d 単純なUIでOKで、自分以外の人への配布の利便性重視なら * libui https://github.com/kojix2/libui を使いますが、どちらも関係者なので、公平な視点ではないですが。ほかにゲームを作りたいなら * https://github.com/ruby2d/ruby2d Qtが好きなら * https://github.com/ryanmelt/qtbindings 私は使ったこと無いけど、メンテナがすごい人なのでWindows向けを作る時に信頼できそう?なのは * https://github.com/larskanis/fxruby だと思います。 この中では、Ruby/Tk は歴史もありバランスがあってバグも比較的少なく安定していると思います。
akira_kano1101

2020/12/30 03:57

お返事ありがとうございます。 GUI、たくさんあるのですね! 個人的にはLibUIはとても気になりました。 また機会を見つけて触ってみたいと思います。 あと、今さきほど、うまくいかなかった理由が判明し、解決できたので発表します。 その原因は、rbenvでruby2.7.2のバージョンを使っていたのですが、これのようです。 rubyのディレクトリを覗いてみると、 ~/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/tk-0.3.0/lib/tkextlib/bwidget.rb にBWidgetが存在しているのを確認できます。 しかし、tkのgemがこのパス中にある2.7.0にがあることがまずかったのだと思います。 ちょうどrubyもバージョンが上がって3.0.0が出ているようだったので、これはもしかするとうまくいくような気がして rbenv global 3.0.0 rbenv rehash してから gem install tk として rubyの中身を確認したところ、次のようにgemsに入っているバージョンが3.0.0となっていました。 ~/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/tk-0.3.0/lib/tkextlib/bwidget.rb そして、最初に教えていただいたコードを動かすと、問題なく動きました。 まだ、マウスホイールでスクロールが動かない状態ではありますが、希望の動作はとりあえずOKです。 少し時間がかかってしまいましたが、ようやく思う形に近づくことができました。 これで解決とさせていただこうと思います。 kojix2さん、色々とここまでお教えいただき、本当にありがとうございました。 また機会があれば、よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問