Qt/Gcc
2013.1.6作成
7-2 分割ウィンドウ〜ウィンドウへの描画〜
コントロールパネルを作るためにいくつか試してみます。
・7-2-1 スプリットウィンドウ(QSplitterウィジェット)のview,scene作成
・7-2-2
スプリットウィンドウへの描画
7-2-1
スプリットウィンドウ(QSplitterウィジェット)のview,scene作成
7-1-1でも作成しましたが、ここでも再度スプリットウィンドウを作成します。そして、
他のビューをコントロールする(描画する)ためのQFrameを基底クラスとしたフォームクラス(コントロールパネルと呼びます)を作成します。
このクラスは、cdrawframeとします。以下の図1-1,1-2,1-3を参照して作成してください。
図1-1
図1-2
図1-3
フレームの大きさは、幅:280、高さ:250とします。これは、geometryもminimumSizeも同じ値にします。
フレームにボタンを貼り付けます。まず、LayoutsからVertical
Layoutを選んで、フレームにドラッグアンドドロップします。
そして、Push Buttonを3つ先ほどのVertical
Layoutエリアに貼り付けていきます。
ボタンは自動的に配置されます。
ボタンの表示を変更します。変更したボタンをダブルクリックするとエディットモードになります。
上からView1Button、View2Button、View3Buttonと名前をつけます。
図2
ボタンの貼り付けと配置
Buttonのプロパティも変更します。ここではobjectNameの値を変更して、貼り付けたButton固有の
名前にします。この名前は後でボタンのslotsとsignalを定義するときに使いますので、
それぞれ固有の名前にします。
ここでもButtonの表記と同じにしておきます。必ずしも同じ名前にする必要はありません。
図3ボタンのプロパティを変更
このコントロールクラスを7-1章と同じようにQSpliteを作成して、QSplitterのひとつのsplite
windowに貼り付けます。
ここでは、mainwindow.hに先ほど作成したクラスのヘッダファイルとクラスの変数を追加します。
以下、mainwindow.hファイルに追加
#include "cdrawframe.h"//QFrameを基底クラスとしたコントロールパネルのクラス宣言
privete:
CDrawFrame
*cotf;//コントロールパネルクラスの変数
今回はsplite
windowに描画するためにQGraphicsViewを貼り付けて、そのViewに対して描画していきます。
この描画はQGraphicsView,QGraphicsScene,QSplitterの各クラスを使うためにmainwindow.hに以下も追加します。
#include <QGraphicsView>
#include
<QGraphicsScene>
#include
<QSplitter>
以下も追加します。
privete:
QGraphicsView
*m_view1;//add
QGraphicsScene *m_scene1;//add
QGraphicsView
*m_view2;//add
QGraphicsScene *m_scene2;//add
QGraphicsView
*m_view3;//add
QGraphicsScene *m_scene3;//add
mainwindow.hには、splite
windowを作成するために以下の関数と変数を追加します。
QSplitter *vsplit2;
QSplitter *vsplit4;
QSplitter
*getFGSplitter(QGraphicsView *lview,CDrawFrame
*cFrame);//GraphicsViewとコントロールパネルを貼り付けるための関数
QSplitter
*getGGSplitter(QGraphicsView *lview1,QGraphicsView
*lview2);//GraphicViewを貼り付けるための関数
次にmainwindow.cppでsplite windowを実装していきます。
はじめに、各splite
windowに貼り付けるためのviewとsceneを作成します。後でviewに描画するためにsceneにGraphicItremを貼り付けます。
次に先ほど作成してコントロールパネルクラスを作成するためにCDrawFrameクラスのコンストラクタを呼び出します。
そして、各splite
windowを配置していきます。
このとき、mainwindowの大きさが小さい場合がありますので、この場合はmainwindowの「デザイン」からmainwindowのgeometryを適当な大きさにします。
ソースコード上でsetGeometry(0,0,640,640);としてもよいです。
プログラムを実行すると以下図4のような画面が表示されます。
図4
以下にソースコードを記載します。
★ソースコード
●mainwindow.h
#ifndef MAINWINDOW_H
#define
MAINWINDOW_H
#include <QMainWindow>
#include
<QGraphicsView>
#include <QGraphicsScene>
#include
<QSplitter>
#include
"cdrawframe.h"//QFrameを基底クラスとしたコントロールパネルのクラス宣言
namespace Ui {
class
MainWindow;
}
class MainWindow : public
QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent =
0);
~MainWindow();
private:
Ui::MainWindow *ui;
QGraphicsView *m_view1;//add
QGraphicsScene
*m_scene1;//add
QGraphicsView
*m_view2;//add
QGraphicsScene
*m_scene2;//add
QGraphicsView
*m_view3;//add
QGraphicsScene *m_scene3;//add
QSplitter
*vsplit2;
QSplitter *vsplit4;
QSplitter
*getFGSplitter(QGraphicsView *lview,CDrawFrame *cFrame);
QSplitter *getGGSplitter(QGraphicsView *lview1,QGraphicsView
*lview2);
CDrawFrame
*cotf;//コントロールパネルクラスの変数
QPixmap px;
};
#endif // MAINWINDOW_H
●mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
:
QMainWindow(parent),
ui(new
Ui::MainWindow)
{
ui->setupUi(this);
// setGeometry(0,0,640,640);//main
windowのサイズはuiでのデザイン画面で大きさを変えてもよい。この関数を呼び出してもよい。今回はデザイン画面で大きさを変えた
m_scene1 = new
QGraphicsScene(); // シーン矩形部分
m_scene1->setSceneRect(-20,-30,640,480);//set view size
,マイナス座標も設定可m_scene->setSceneRect(-320,-240,640,480);
//viewを大きめにとっておく。windowをドラッグしてviewの領域を超えると表示した画像がずれてくる
m_view1 = new QGraphicsView();//viewの生成
m_view1->setScene(m_scene1);//viewにsceneをセット
m_scene2 = new
QGraphicsScene(); // シーン矩形部分
m_scene2->setSceneRect(-20,-30,640,480);//set view size
,マイナス座標も設定可m_scene->setSceneRect(-320,-240,640,480);
//viewを大きめにとっておく。windowをドラッグしてviewの領域を超えると表示した画像がずれてくる
m_view2 = new QGraphicsView();//viewの生成
m_view2->setScene(m_scene2);//viewにsceneをセット
m_scene3 = new
QGraphicsScene(); // シーン矩形部分
m_scene3->setSceneRect(-20,-30,640,480);//set view size
,マイナス座標も設定可m_scene->setSceneRect(-320,-240,640,480);
//viewを大きめにとっておく。windowをドラッグしてviewの領域を超えると表示した画像がずれてくる
m_view3 = new QGraphicsView();//viewの生成
m_view3->setScene(m_scene3);//viewにsceneをセット
cotf = new CDrawFrame();//コントロールパネルクラスを確保するためにコンストラクタを呼び出す。
vsplit2=getFGSplitter(m_view1,cotf);//それぞれのビューとコントロールパネルをsplite
windowに
vsplit4=getGGSplitter(m_view2,m_view3);//同上
//以下で上記でビューを貼り付けたsplite
windowをさらにsplite windowにはりつけて4分割している。
QSplitter *hsplit =
new QSplitter(Qt::Horizontal);
hsplit->addWidget(vsplit2);
QSplitter *hsplit1 = new
QSplitter(Qt::Horizontal);
hsplit1->addWidget(vsplit4);
hsplit->addWidget(hsplit1);//mainwindowのセントラルウィジェットとして4分割したsplite windowを貼り付ける。
setCentralWidget(hsplit);
}
MainWindow::~MainWindow()
{
delete
ui;
}
QSplitter *MainWindow::getFGSplitter(QGraphicsView *lview,CDrawFrame
*cFrame)
{
/**splitterの設定*/
QSplitter *vsplit =
new QSplitter(Qt::Vertical);
vsplit->addWidget(lview);
QSplitter *vsplit1 = new
QSplitter(Qt::Vertical);
vsplit1->addWidget(cFrame);
vsplit->addWidget(vsplit1);
return
vsplit;
}
QSplitter *MainWindow::getGGSplitter(QGraphicsView
*lview1,QGraphicsView *lview2)
{
/**splitterの設定*/
QSplitter *vsplit =
new
QSplitter(Qt::Vertical);
vsplit->addWidget(lview1);
QSplitter *vsplit1 = new
QSplitter(Qt::Vertical);
vsplit1->addWidget(lview2);
vsplit->addWidget(vsplit1);
return vsplit;
}
7-2-2
スプリットウィンドウへの描画(QGraphicsItemの利用)
各スプリットウィンドウへの描画を実施します。描画にはQGraphicsItemのQGraphicsEllipseItemを利用しました。
各ビューに対して描画する関数を作成し、mainwindowのコンストラクタから呼び出します。
関数は以下のようにします。
void MainWindow::InitView1()
{
item1 =
new QGraphicsEllipseItem(100, 100, 200, 100);
item1->setBrush(QBrush(QColor("pink")));
m_scene1 = new
QGraphicsScene(); // シーン矩形部分
m_scene1->setSceneRect(-20,-30,640,480);//set view size
,マイナス座標も設定可m_scene->setSceneRect(-320,-240,640,480);
//viewを大きめにとっておく。windowをドラッグしてviewの領域を超えると表示した画像がずれてくる
m_scene1->addItem(item1);
m_view1 = new
QGraphicsView();//viewの生成
m_view1->setScene(m_scene1);//viewにsceneをセット
}
図5
★ソースコード
●mainwindow.h
#ifndef
MAINWINDOW_H
#define
MAINWINDOW_H
#include <QMainWindow>
#include
<QGraphicsView>
#include <QGraphicsScene>
#include
<QSplitter>
#include <QGraphicsItem>
#include
"cdrawframe.h"//QFrameを基底クラスとしたコントロールパネルのクラス宣言
namespace Ui {
class
MainWindow;
}
class MainWindow : public
QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent =
0);
~MainWindow();
private:
Ui::MainWindow *ui;
QGraphicsView *m_view1;//add
QGraphicsScene
*m_scene1;//add
QGraphicsView
*m_view2;//add
QGraphicsScene
*m_scene2;//add
QGraphicsView
*m_view3;//add
QGraphicsScene *m_scene3;//add
QSplitter
*vsplit2;
QSplitter *vsplit4;
QGraphicsEllipseItem
*item1;//描画用
QGraphicsEllipseItem
*item2;
QGraphicsEllipseItem *item3;
void InitView1();
void InitView2();
void InitView3();
QSplitter
*getFGSplitter(QGraphicsView *lview,CDrawFrame *cFrame);
QSplitter *getGGSplitter(QGraphicsView *lview1,QGraphicsView
*lview2);
CDrawFrame
*cotf;//コントロールパネルクラスの変数
QPixmap px;//今回のプログラムでは使わない。
};
#endif //
MAINWINDOW_H
●mainwindow.cpp
#include "mainwindow.h"
#include
"ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
:
QMainWindow(parent),
ui(new
Ui::MainWindow)
{
ui->setupUi(this);
// setGeometry(0,0,640,640);//main
windowのサイズはuiでのデザイン画面で大きさを変えてもよい。この関数を呼び出してもよい。今回はデザイン画面で大きさを変えた
//各viewとsceneを確保して、初期状態の描画をするための関数
InitView1();
InitView2();
InitView3();
cotf = new CDrawFrame();//コントロールパネルクラスを確保するためにコンストラクタを呼び出す。
vsplit2=getFGSplitter(m_view1,cotf);//それぞれのビューとコントロールパネルをsplite
windowに
vsplit4=getGGSplitter(m_view2,m_view3);//同上
//以下で上記でビューを貼り付けたsplite
windowをさらにsplite windowにはりつけて4分割している。
QSplitter *hsplit =
new QSplitter(Qt::Horizontal);
hsplit->addWidget(vsplit2);
QSplitter *hsplit1 = new
QSplitter(Qt::Horizontal);
hsplit1->addWidget(vsplit4);
hsplit->addWidget(hsplit1);//mainwindowのセントラルウィジェットとして4分割したsplite windowを貼り付ける。
setCentralWidget(hsplit);
}
MainWindow::~MainWindow()
{
delete
ui;
}
QSplitter *MainWindow::getFGSplitter(QGraphicsView *lview,CDrawFrame
*cFrame)
{
/**splitterの設定*/
QSplitter *vsplit =
new QSplitter(Qt::Vertical);
vsplit->addWidget(lview);
QSplitter *vsplit1 = new
QSplitter(Qt::Vertical);
vsplit1->addWidget(cFrame);
vsplit->addWidget(vsplit1);
return
vsplit;
}
QSplitter *MainWindow::getGGSplitter(QGraphicsView
*lview1,QGraphicsView *lview2)
{
/**splitterの設定*/
QSplitter *vsplit =
new
QSplitter(Qt::Vertical);
vsplit->addWidget(lview1);
QSplitter *vsplit1 = new
QSplitter(Qt::Vertical);
vsplit1->addWidget(lview2);
vsplit->addWidget(vsplit1);
return vsplit;
}
void
MainWindow::InitView1()
{
item1 = new
QGraphicsEllipseItem(100, 100, 200, 100);
item1->setBrush(QBrush(QColor("pink")));
m_scene1 = new
QGraphicsScene(); // シーン矩形部分
m_scene1->setSceneRect(-20,-30,640,480);//set view size
,マイナス座標も設定可m_scene->setSceneRect(-320,-240,640,480);
//viewを大きめにとっておく。windowをドラッグしてviewの領域を超えると表示した画像がずれてくる
m_scene1->addItem(item1);
m_view1 = new
QGraphicsView();//viewの生成
m_view1->setScene(m_scene1);//viewにsceneをセット
}
void
MainWindow::InitView2()
{
item2 = new
QGraphicsEllipseItem(100, 100, 200, 100);
item2->setBrush(QBrush(QColor("blue")));
m_scene2 = new
QGraphicsScene(); // シーン矩形部分
m_scene2->setSceneRect(-20,-30,640,480);//set view size
,マイナス座標も設定可m_scene->setSceneRect(-320,-240,640,480);
//viewを大きめにとっておく。windowをドラッグしてviewの領域を超えると表示した画像がずれてくる
m_scene2->addItem(item2);
m_view2 = new
QGraphicsView();//viewの生成
m_view2->setScene(m_scene2);//viewにsceneをセット
}
void
MainWindow::InitView3()
{
item3 = new
QGraphicsEllipseItem(100, 100, 200, 100);
item3->setBrush(QBrush(QColor("red")));
m_scene3 = new
QGraphicsScene(); // シーン矩形部分
m_scene3->setSceneRect(-20,-30,640,480);//set view size
,マイナス座標も設定可m_scene->setSceneRect(-320,-240,640,480);
//viewを大きめにとっておく。windowをドラッグしてviewの領域を超えると表示した画像がずれてくる
m_scene3->addItem(item3);
m_view3 = new
QGraphicsView();//viewの生成
m_view3->setScene(m_scene3);//viewにsceneをセット
}