(趣味で)C++でやっています。
C++ではGUIはQtが楽らしいので使ってみました。
以前質問したDLL云々は何とか解決しました。
QtCreator付属のヘルプ ( "ヘルプ(H)" のやつ )や
他の方のPDFを見ながら挑戦しています。
私個人はなんとなく扱いにくいので
せめてJavaのSwing風 ( なんかもう一方あった気がしますが... )にできないかなと思い、
DLL化しようと思いました。
大雑把な考えとしては
まずDLL及び実行ファイルで呼びだすインターフェースクラス ( IEventLinstener, IButton etc. ) を定義し、
IButtonをDLL内で継承して Factoryパターンを適用して CreateButtonInstance関数 ( もちろんオープン。 )で生成する。
IEventListener は 実行ファイル側で実装し、CreateButtonInstance関数に渡して、WButton ( IButton実装 ) のコンストラクタに渡して生成&登録。
という感じです。
読みにくいので...
[ DLL内 ] 1. IEventListener定義 2. IButton定義 3. IButtonを実装したWButtonを定義 4. IButtonとして返す CreateButtonInstance関数を定義 ( opened ) [実行ファイル] 1. IEventListener定義 2. IButton定義 3. IEventListenerを実装したイベント系クラスを定義 4. Windows API の動的リンクを用いて CreateButtonInstance等を使えるようにする 5. CreateButtonInstanceに 3のオブジェクト等の情報を渡して IButton型のオブジェクト ( 中身は WButton ) を生成する
という感じです。
まずは動かないと意味がないのでDLL化する前に そもそものQtの使い方を学び、どうやったら動くか試してみました。
継承もせずにコンポジションもせずにそのまま使う方法だと
C++
1// インクルード等はしてあるものとする。 2int main( int argc, char* argv[] ){ 3 QApplication app( argc, argv ); 4 5 // メインウィンドウ用? 6 QWidget* window = new QWidget(); 7 8 // メインウィンドウのサイズ等の変更 9 window->resize( 500, 600 ); 10 window->move( 10, 10 ); 11 12 QPushButton* button1 = new QPushButton( "button1" ); 13 14 button1->resize( 20, 100 ); 15 button1->move( 10, 10 ); 16 17 button1->setParent( window ); // button1を windowに登録 18 19 window->show(); 20 21return app.exec(); 22}
だとわかりました。( もしかするとQWidgetは QMainWindowとかみたいな別のクラスになるかもしれないが。 )
( もちろん、deleteする必要があると思いますが。 サンプルなので。 )
Windows API だと ウィンドウプロシージャに相当するやつがあるはずなので参考にしたPDFを見ると
QObject::connect非メンバ関数でやるらしいので
C++
1// イベントリスナーインターフェース。実行ファイルにも公開するつもり。 2// Windows API で言えば ウィンドウプロシージャに相当。 3// コントロールごとに登録するメンバ関数が違う? 4class IEventListener{ 5 public: 6 IEventListener(){} 7 8 virtual void buttonClicked( void ) = 0; 9}; 10 11// BUTTON用インターフェース。 12class IButton{ 13 public: 14 virtual ~IButton(){} 15 virtual std::string getText( void ) = 0; 16 virtual bool setText( const std::string text ) = 0; 17}; 18 19 20// 実際のButtonクラス。内部にQPushButtonを持ち、イベントinterfaceと親ウィンドウをコンストラクタで引き受けて 21// イベントの設定も行う。 22class WButton : public IButton, public QWidget{ 23 public: 24 WButton( QWidget* window = nullptr, IEventListener *e = nullptr ) : event(e){ 25 button1 = new QPushButton("button1"); 26 button1->setParent( window ); 27 28 if( e != nullptr ){ 29 QObject::connect( button1, SIGNAL( clicked() ), this, SIGNAL( PushButtonMessage() ) ); 30 } 31 } 32 33 std::string getText( void ){ 34 35 } 36 37 bool setText( const std::string text ){ 38 39 } 40 41 signals: 42 void PushButtonMessage( void ){ 43 event->buttonClicked(); 44 } 45 private: 46 QPushButton* button1; 47 IEventListener* event; 48}; 49 50 51// ----------------------------- // 52 53// ボタン用イベントクラス。実際には実行ファイル側で定義する予定。 54class ButtonEvent : public IEventListener{ 55 public: 56 ButtonEvent(){} 57 ~ButtonEvent(){} 58 59 void buttonClicked( void ){ 60 MessageBox( NULL, "button1 clicked", "", MB_OK ); 61 } 62 protected: 63 private: 64 65}; 66 67// --------- // 68 69 70int main( int argc, char *argv[] ){ 71 QApplication app( argc, argv ); 72 73 QWidget* window = new QWidget(); 74 window->resize( 500, 600 ); 75 76 IEventListener* event = new ButtonEvent(); 77 78 IButton* Button1 = new WButton( window, event ); 79 80 window->show(); 81 82return app.exec(); 83} 84
のようにしてみました。
コンパイルは通りましたが、私の予想結果は
"button1" ボタンが押された -> "button1 clicked"というメッセージボックスの表示
という感じなのですが、実際には "button1" ボタンが押されても無反応です。
( 空の関数を実行したっていう感じの。 )
出来れば QPushButtonを実行ファイルに見せずに イベント登録や基本的な動きをDLLにして、
実行ファイルは 実際に行うイベントを定義して、ifstream, ofstreamみたいに使うだけ...
という風にしたいのですが...
一応自分なりに思いついたものは試してみましたがうまくいかないのです。
[情報]
言語: C++
コンパイラ: MinGW
宜しくお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/09/09 09:36
2017/09/09 09:39