今日は、いくつかのトピックを取り上げます。
2. 1.拡張の原則
2.ソリューションの技術面
3.拡張機能デバッグツール
拡張原則
主な目標は使いやすさでした。 ご存知のように、phpは1つのスレッドで動作します。もちろん、スレッドを作成して操作できる拡張機能がありますが、スレッドを使用する場合、それらの管理に関連する問題が発生します。 そして原則として、これは必要ではありません。 したがって、私にとって、仕事の論理の単純さ、すなわち クラスメソッドを呼び出す場合:
$result = $gtk->alert(" !"); var_dump($result);
その後、次の結果が得られます。
そして、[OK]ボタンをクリックすると:
つまり、概念はPHPに似ており、launch->任意のシーケンシャルアクションの実行->スクリプトの完了です。
問題の技術面
拡張機能をメイン部分(main.cpp)とモジュールに分割し、それぞれがphpで使用する1つまたは別のウィジェットを実装することにしました。 これを行うために、コード自体があるsrc /フォルダーを作成し、すべてのソースを新しいディレクトリに転送しました。 ソースを移行したら、拡張子が.cppのファイルがある場所を示すように、Makefileを次のように修正する必要があります。
SOURCES = $(wildcard src/*.cpp)
以下は、プレビューウィンドウを実装するクラスの例です。
同じスクリーンと帽子
ファイルpreviewWindow.h
class GtkPhpPreviewWindow { private: Gtk::Window *mainWindow = nullptr; // protected: int statusUpload = 0; // upload int statusCancel = 0; // cancel public: std::string preview(char *fileSrc); // void uploadClick(); // callback void cancelClick(); std::string getStatusUpload(); // };
次に、ファイル自体を見て、つまりプレビューを分析します。
リストのプレビュー
/** * run preview window */ std::string GtkPhpPreviewWindow::preview(char *fileSrc) { int argc = 0; char **argv = NULL; auto app = Gtk::Application::create(argc, argv, "org.gtkmm.gtkphp7"); auto refBuilder = Gtk::Builder::create(); try { refBuilder->add_from_file("picview.glade"); } catch (const Glib::FileError &ex) { std::cerr << "FileError: " << ex.what() << std::endl; } catch (const Gtk::BuilderError &ex) { std::cerr << "BuilderError: " << ex.what() << std::endl; } refBuilder->get_widget("window1",mainWindow); Gtk::Image *image = nullptr; refBuilder->get_widget("preview", image); Gtk::Button *buttonUpload = nullptr; refBuilder->get_widget("upload", buttonUpload); buttonUpload->signal_clicked().connect( sigc::mem_fun(*this, &GtkPhpPreviewWindow::uploadClick) ); Gtk::Button *buttonCancel = nullptr; refBuilder->get_widget("cancel", buttonCancel); buttonCancel->signal_clicked().connect( sigc::mem_fun(*this, &GtkPhpPreviewWindow::cancelClick) ); image->set(fileSrc); app->run(*mainWindow); return getStatusUpload(); }
この方法は非常に長いことが判明したため、重要な点のみを考慮しようとします。
auto app = Gtk::Application::create(argc, argv, "org.gtkmm.gtkphp7"); auto refBuilder = Gtk::Builder::create(); refBuilder->add_from_file("picview.glade");
これらの3行を使用して、アプリケーションインスタンスとビルダー(PHPのファクトリーのようなもの)を作成します。 そして、picview.gladeファイルをロードします。
はい、フォームを簡単にするためにgtkのフォームエディターであるgladeを使用しました。
空き地でプレビュー
要素の位置(またはレイアウト)をxml形式で記述するファイルを作成する。 ロードして、必要な要素を取得するだけです。
Gtk::Button *buttonCancel = nullptr; refBuilder->get_widget("cancel", buttonCancel); // buttonCancel->signal_clicked().connect( sigc::mem_fun(*this, &GtkPhpPreviewWindow::cancelClick) // );
cancelClickで:
/** * callback cancel button */ void GtkPhpPreviewWindow::cancelClick() { statusCancel = 1; delete mainWindow; }
mainWindowを削除し、キャンセルボタンの状態を押された状態に設定します。 最後のタッチでアプリケーションを起動します(この場合、ウィンドウを表示します):
app->run(*mainWindow);
この時点で、ウィンドウを開いたままにして実行されなくなる「ループ」が作成されます。 しかし、ボタンをクリックした時点で、mainWindowを削除すると、プログラムはメソッドに進みます。
/** * get status upload * @return */ std::string GtkPhpPreviewWindow::getStatusUpload() { if (statusUpload == 1) { return "upload"; } else { return "cancel"; } }
クリックされたものを示す文字列を返します。
デバッグツール
おそらくすべての「C」プログラマーはgdbを知っていますが、すべてのphpプログラマーがgdbについて知っているわけではありません。 たとえば、apacheがセグメンテーション違反を起こしてコアダンプを生成した理由を、どういうわけか彼らに見つけました...
したがって、gdb-cおよびc ++のgnuデバッガーデバッガーは多くのことを実行できます。ブレークポイントの設定、メモリダンプの読み取り、スタックトレースの構築です。 したがって、拡張機能がsegfaultまたはむしろphpでクラッシュすることを想像してください(拡張機能はインタープリターに接続されているため)。 すべてがコンパイルされ、動作するはずです。 しかし、ありません。
まず、-gオプションを使用してプロジェクトを再コンパイルする必要があります。 このため、Makefileを修正しました。
COMPILER = g++ -g
そして、このオプションでコンパイルされました。 その後、コアダンプと呼ばれるphpスクリプトが作成され、gdbの下で実行されました。
$ gdb php $ /.. gdb ../ (gdb) run ./test.php # $ .... coredump (gdb) bt # backtrace
したがって、gdbは発生したエラーとバックトレースを表示します。これにより、問題が何であるかを正確に判断できます(少なくとも、私はまだ小さなプロジェクトを持っています)。
結論として
拡張機能のデバッグ後、guiをスクリーンショットに統合しました。
新しいコード
#!/usr/bin/php <?php require_once('classis/autoload.php'); class screenShoter { protected $_nameScreenshot = null; protected $_config = null; protected $_gtk = null; public function __construct() { $this->_gtk = new GtkPhp(); $request = new Request(); if(isset($argv[1]) && $argv[1] == '--getToken') { echo $request->getOauthLink();die; } $home = $_SERVER['HOME']; $this->_config = include($home . '/.config/scrphp/config.php'); $this->_nameScreenshot = date('Y_m_d_G_i_s_') . 'screen.png'; $this->scrot(); } public function scrot() { $this->_gtk->alert(", Ok , "); system('scrot -s /tmp/'.$this->_nameScreenshot); $resultPrev = $this->_gtk->preview('/tmp/'.$this->_nameScreenshot); if($resultPrev == 'upload') { $this->upload(); } else { $this->scrot(); } } public function upload() { $request = new Request(); $result = $request ->setToken($this->_config['token']) ->setFileNameOnDisk($this->_nameScreenshot) ->setPathToFile('/tmp/'.$this->_nameScreenshot) ->upload() ->publicateFile(); $url = $result['public_url']; $this->_gtk->alert(" :".$url); } } new screenShoter();
このスクリプトは3つのステップで機能します。
1.スクリーンショットを撮る方法に関するヒントを表示するアラート:
2.サイトを選択してスクリーンショットを作成すると、プレビューが開きます。
3.アップロードボタンをクリックすると、リンクを含むアラートが表示されます
そして結論として。
リポジトリへのリンク:
1.gtkPHP7
2. srcphpスクリーンショット
依存関係:
1. gtkmm3
2.gtk3
3.空き地