質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Tcl

Tclは、インタープリタ型のプログラミング言語。リスト処理や連想配列といった特長を持ち、文法もシンプルです。拡張や他言語への組み込みが簡単にでき、アプリケーション拡張にための組み込み言語として用いられます。

Ruby

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

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

Q&A

解決済

1回答

886閲覧

Ruby Tk + Selenium GUIが反応しない

qiyuren

総合スコア29

Tcl

Tclは、インタープリタ型のプログラミング言語。リスト処理や連想配列といった特長を持ち、文法もシンプルです。拡張や他言語への組み込みが簡単にでき、アプリケーション拡張にための組み込み言語として用いられます。

Ruby

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

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

0グッド

0クリップ

投稿2021/03/13 10:34

前提・実現したいこと

以下のソースのように、「スタート」ボタンで、selenium_programメソッド内のSelenium起動後、
任意のタイミングで「変数を変更」ボタンで、selenium_programメソッド内のインスタンス変数に値を代入し、seleniumの挙動を変えたいのですが、
一度「スタート」ボタンを押すと、ビジーカーソルになり、どのボタンも反応しません。

解決策をご教授いただけないでしょうか。

該当のソースコード

ruby

1require "selenium-webdriver" 2require "tk" 3 4def selenium_program 5 #seleniumのプログラム 6end 7 8TkRoot.new 9 10TkButton.new( 11 nil, 12 text: 'start', 13 font: ["", 20], 14 command: proc{selenium_program()}, 15 height: 1, 16 width: 10 17).pack 18 19TkButton.new( 20 nil, 21 text: '変数を変更', 22 font: ["", 20], 23 command: proc{#selenium_programメソッド内のインスタンス変数を変更する}, 24 height: 1, 25 width: 10 26).pack 27 28Tk.mainloop 29

補足情報(FW/ツールのバージョンなど)

Ruby 2.6.5

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

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

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

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

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

guest

回答1

0

ベストアンサー

Ruby/Tk のメインループは、Threadとの相性が悪いことで有名です。
seleniumの内部でもThreadを利用しているようなので、それがバッティングしているのではないでしょうかね。
https://github.com/SeleniumHQ/selenium/search?l=Ruby&q=Thread

私はWebエンジニアではないので、seleniumのことはわかりませんが、こういう場合は、drubyを利用して、3つのRubyスクリプトに分割して通信させることが多いです。drubyは異なるプロセスの間でRubyのオブジェクトをやりとりさせる仕組みです。具体的には

https://docs.ruby-lang.org/ja/latest/library/drb.html

サーバー

ruby

1require 'drb/drb' 2 3SERVER_URI="druby://localhost:8787" 4 5object = [] # 共有オブジェクト 6 7fork{ 8 DRb.start_service(SERVER_URI, object, :safe_level => 1) 9 DRb.thread.join 10} 11 12Process.waitpid(child_pid)

クライアント1 (Ruby/Tk関連のコード)

ruby

1require 'drb/drb' 2 3SERVER_URI="druby://localhost:8787" 4# DRb.start_service 5object = DRbObject.new_with_uri(SERVER_URI)

クライアント2 (selenium関連のコード)

ruby

1require 'drb/drb' 2 3SERVER_URI="druby://localhost:8787" 4# DRb.start_service 5object = DRbObject.new_with_uri(SERVER_URI)

みたいな感じです。クライアント1, 2の間でサーバーを仲介してRubyのオブジェクトを共有できます。こんな感じでRuby/Tkでサーバーを仲介してselenium側に命令を出すことができます。やってないのでわかりませんがビジーにはならなくなるのではないかと思います。3つもRubyスクリプトを動かさなければならないので面倒ですが、drubyサーバーを挟んで1,2が別々に動くので、ビジーになりにくくなります。
(objectはMarshal.dumpを使って通信してるっぽいので、重すぎるものは好ましくありません)

最近はRactorという機構が開発されているようなので、そういったものも使えるかも知れません(わかりません)

投稿2021/03/20 03:16

kojix2

総合スコア49

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問