C++でQTアプリ(その10) 描画処理
Ruby/Qteの勉強で行ったQPainterを用いた線の描画プログラムを書いてみた。画面下のテキストエリアの関数の定義を書き、Drawボタンを押すと関数の曲線を描きます。
関数の評価の方法がわからない(evalみたいなのはC++にもあるのだろうか)のでslcalcのソースを使わせてもらいました。
描画はQPainter *pを宣言してp->begin()からp->end()の間で描画内容を記述します。今回はX=-319〜319の範囲での定義した関数によるYの値で決まる座標に線を引いています。
drawtest.h
#ifndef DRAWTEST_H #define DRAWTEST_H #include <qmainwindow.h> #include <qwidget.h> #include <qlineedit.h> #include <qpushbutton.h> #include <qstring.h> #include <qpen.h> #include <qpainter.h> #include "calc.h" // slcalcのソース利用 #define MAXNN 100 // max name number #define MAXIC 512 // max input characters #define MAXRC 64 // max result characters #define MAXFC 16 // max format characters #define MAXSC 128 // max standard characters #define MAXIFC 16384 // max input file characters class DrawTest : public QMainWindow{ Q_OBJECT public: DrawTest(QWidget *parent = 0, const char *name = 0); // ~DrawTest(); private: QWidget *w; QLineEdit *eb; QPushButton *pb; private: int func( int x ); void calculate( QString t ); private slots: void slot_draw(); }; #endif
drawtest.cpp
#include "drawtest.h" int g_bFormat = 0; // claculated result format n:0 f:1 e:2 int g_bAng = 1; // angle base rad:0 deg:1 bool g_bClear = true; // clear input text at next key int g_bBufCount = 0; // buffer count double g_bX = 0; // calculated result bool g_bError = false; // make error ? bool g_bCFedited = false; // conf file edited ? char ws[MAXIFC]; QString g_sFormatN = "%g"; QString g_sFormatF = "%f"; QString g_sFormatE = "%21.15e"; bool g_sFlagBuffer = true; calc calc_; DrawTest::DrawTest(QWidget *parent, const char *name) : QMainWindow(parent, name) { setCaption("Draw Test"); w = new QWidget( this ); // 描画用ウィジェット w->setGeometry(0, 0, 640, 370); eb = new QLineEdit( this ); eb->setGeometry(0, 370, 580, 40); eb->clear(); pb = new QPushButton("Draw", this); pb->setGeometry(580, 370, 60, 40); connect( pb, SIGNAL(clicked()), this, SLOT(slot_draw()) ); } void DrawTest::slot_draw() { calc_.clear(); // calc_クリア w->erase(); // 画面クリア QString t = eb->text(); // 式を取得 calculate( t ); // 式設定 const QPen pen( Qt::blue, 2); // ペン色、太さ constが必須 QPainter *p = new QPainter(); p->begin( w ); // 描画開始 p->setPen( pen ); int x = -320, y; y = func( x ); // y値計算 p->moveTo(x + 320, 185 - y); // 初期座標 for( x = -319; x < 320; x++){ y = func( x ); p->lineTo(x + 320, 185 - y);// 一つ前の座標から線を描く } p->end(); // 描画終了 } int DrawTest::func( int x ) { QString t; t.sprintf("S(%d)", x); calculate( t ); double d = g_bX; if(d > 1000) d = 1000; if(d < -1000) d = -1000; return( (int)d ); } // slcalcのソースを利用 void DrawTest::calculate( QString t ) { char s[MAXIC], tx[MAXRC], f[MAXFC]; int i, j; strcpy(f, "%g"); if (t.length() >= MAXIC) t = t.left(MAXIC - 1); strcpy(s, t); calc_.set_ang(g_bAng); // calculation i = calc_.result(s, &g_bX, tx, f); if ((i==1)||(i==2)) { calc_.list(ws, MAXIFC); calc_.clear(); for(i=j=0; ws[i]; i++) if (ws[i]=='\n') { ws[j] = 0; calc_.result(ws, &g_bX, tx, f); j=0; } else ws[j++] = ws[i]; ws[j] = 0; calc_.result(ws, &g_bX, tx, f); i = calc_.result(s, &g_bX, tx, f); } g_bError = (i != 0); // set buffer count g_bBufCount = 1; // text clear at next input g_bClear = true; }