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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

0回答

234閲覧

表示領域の端をクリックした時自動でスケールを変えたい

yoshiki0424yi

総合スコア12

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/09/18 01:36

前提・実現したいこと

C++でデータの読み込み, 追加, 書き出しを行うプログラムを作っています.
実行時の表紙領域の端側をクリックした時に自動でスケールが変わる仕様にしたいと考えています.

発生している問題

自分で行ったソースの変更では上や右へのスケール変更は成功したが,
左や下へのスケール変更が行われません.

該当のソースコード

maincpp

1#include <gtkmm/application.h> 2 3#include "MyWindow.h" 4 5int main( ){ 6 auto app = Gtk::Application::create( ); 7 ClusteringDataApp::MyWindow myWindow; 8 9 return app->run( myWindow ); 10} 11

MyWindowcpp

1#include "MyWindow.h" 2 3namespace ClusteringDataApp{ 4 MyWindow::MyWindow( ) : 5 openButton_( "LOAD" ), saveButton_( "SAVE&EXIT" ), data_( 0 ), drawingArea_( data_ ) { 6 7 set_border_width( 5 ); 8 openButton_.signal_clicked( ).connect( 9 sigc::mem_fun( *this, &MyWindow::on_openButton_clicked ) 10 ); 11 saveButton_.signal_clicked( ).connect( 12 sigc::mem_fun( *this, &MyWindow::on_saveButton_clicked ) 13 ); 14 vBox_.pack_start( openButton_, false, true ); 15 drawingArea_.set_size_request( 600, 600 ); 16 vBox_.pack_start( drawingArea_, true, true ); 17 18 add( vBox_ ); 19 show_all( ); 20 } 21 22 void MyWindow::on_openButton_clicked( ){ 23 data_.clear( ); 24 Gtk::FileChooserDialog dialog( *this, "Load from", Gtk::FILE_CHOOSER_ACTION_OPEN ); 25 dialog.add_button( Gtk::Stock::OPEN, Gtk::RESPONSE_OK ); 26 dialog.add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL ); 27 28 auto filterText = Gtk::FileFilter::create( ); 29 filterText->set_name( "プレーンテキスト" ); 30 filterText->add_pattern( "*.txt" ); 31 dialog.add_filter( filterText ); 32 33 if( Gtk::RESPONSE_OK == dialog.run( ) ){ 34 std::string dataFileName = dialog.get_filename( ); 35 36 auto ifs = std::ifstream( dataFileName, std::ios::in ); 37 while( ifs.good( ) ){ 38 std::string aLine; 39 std::getline( ifs, aLine ); 40 std::istringstream iss( aLine ); 41 42 std::vector<double> lineData; 43 double temp; 44 while( iss >> temp ) lineData.push_back( temp ); 45 46 if( !lineData.empty( ) ) 47 data_.emplace_back( std::make_pair( lineData.at( 0 ), lineData.at( 1 ) ) ); 48 } 49 } 50 if( !data_.empty( ) ){ 51 vBox_.remove( openButton_ ); 52 vBox_.pack_end( saveButton_, false, true ); 53 saveButton_.show( ); 54 } 55 } 56 57 void MyWindow::on_saveButton_clicked( ){ 58 const std::string fileName = "newData.txt"; 59 std::cerr << data_.size( ) << " data is written to " << fileName << "\n"; 60 61 auto ofs = std::ofstream( fileName, std::ios::out ); 62 if( ofs.good( ) ) 63 for( const auto& pair : data_ ) 64 ofs << pair.first << "\t" << pair.second << "\n"; 65 ofs.close( ); 66 67 hide( ); 68 } 69}

MyWindowh

1#ifndef MYWINDOW_INCLUDED 2#define MYWINDOW_INCLUDED 3#include <gtkmm/window.h> 4#include <gtkmm/button.h> 5#include <gtkmm/hvbox.h> 6#include <gtkmm/filechooserdialog.h> 7#include <gtkmm/stock.h> 8#include <gtkmm/filefilter.h> 9#include <giomm.h> 10 11#include <iostream> 12#include <vector> 13#include <utility> 14#include <fstream> 15#include <string> 16#include <sstream> 17 18#include "MyDrawingArea.h" 19namespace ClusteringDataApp{ 20 class MyWindow : public Gtk::Window{ 21 public: 22 MyWindow( ); 23 virtual ~MyWindow( ) = default; 24 25 protected: 26 virtual void on_openButton_clicked( ); 27 virtual void on_saveButton_clicked( ); 28 29 Gtk::Button openButton_; 30 Gtk::Button saveButton_; 31 Gtk::VBox vBox_; 32 33 dataType< > data_; 34 35 MyDrawingArea drawingArea_; 36 }; 37} 38#endif

MyDrawingAreacpp

1#include "MyDrawingArea.h" 2 3namespace ClusteringDataApp{ 4 MyDrawingArea::MyDrawingArea( dataType< >& data ) : 5 data_( data ){ 6 add_events( Gdk::BUTTON_PRESS_MASK ); 7 } 8 9 void MyDrawingArea::prepareProperties( ) { 10 minMaxPairForX0_ = std::minmax_element( data_.cbegin( ), data_.cend( ), 11 [ ]( const std::pair< double, double >& a, const std::pair< double, double >& b ){ 12 return a.first > b.first; 13 } ); 14 minMaxPairForX1_ = std::minmax_element( data_.cbegin( ), data_.cend( ), 15 [ ]( const std::pair< double, double >& a, const std::pair< double, double >& b ){ 16 return a.second > b.second; 17 } ); 18 19 width_ = get_width( ); 20 height_ = get_height( ); 21 } 22 23 bool MyDrawingArea::on_draw( const Cairo::RefPtr<Cairo::Context>& cr ){ 24 if( 0 == data_.size( ) ) return false; 25 26 prepareProperties( ); 27 auto x0band = (*minMaxPairForX0_.first).first - (*minMaxPairForX0_.second).first; 28 auto x1band = (*minMaxPairForX1_.first).second - (*minMaxPairForX1_.second).second; 29 30 auto f0 = [ & ]( double x ){ 31 return ( x - (*minMaxPairForX0_.second).first ) * width_ / x0band; }; 32 auto f1 = [ & ]( double x ){ 33 return height_ - ( x - (*minMaxPairForX1_.second).second ) * height_ / x1band; }; 34 35 cr->set_source_rgb( 1., 1., .8 ); // LIGHT YELLOW 36 cr->rectangle( 0.,0., width_, height_ ); 37 cr->fill( ); 38 39 cr->set_source_rgb( 1., 0., 0. ); // RED 40 for( const auto& pair : data_ ){ 41 cr->arc( 42 f0( pair.first ), f1( pair.second ), 43 3., 0., 2. * G_PI ); // size 3. circle 44 cr->fill( ); 45 } 46 return false; 47 } 48 49 bool MyDrawingArea::on_button_press_event( GdkEventButton* event ){ 50 if( 0 == data_.size( ) ) return false; 51 52 prepareProperties( ); 53 auto x0band = (*minMaxPairForX0_.first).first - (*minMaxPairForX0_.second).first; 54 auto x1band = (*minMaxPairForX1_.first).second - (*minMaxPairForX1_.second).second; 55 56 auto f0 = [ & ]( double x ){ 57 return (*minMaxPairForX0_.second).first + x * x0band / width_; }; 58 auto f1 = [ & ]( double x ){ 59 return x1band * ( height_ - x ) / height_ + (*minMaxPairForX1_.second).second; }; 60 61 if( ( event->type == GDK_BUTTON_PRESS ) && ( event->button == 1 ) ) 62 data_.emplace_back( f0( event->x ), f1( event->y ) ); 63 64 queue_draw( ); 65 return false; 66 } 67}

MyDrawingAreah

1#ifndef MYDRAWINGAREA_INCLDED 2#define MYDRAWINGAREA_INCLDED 3#include <gtkmm/drawingarea.h> 4 5#include <vector> 6#include <utility> // std::pair 7#include <algorithm> 8 9namespace ClusteringDataApp{ 10 template < typename T = double > 11 using dataType = std::vector< std::pair<T, T> >; 12 13 class MyDrawingArea : public Gtk::DrawingArea{ 14 public: 15 explicit MyDrawingArea( dataType< >& data ); 16 virtual ~MyDrawingArea( ) = default; 17 18 protected: 19 bool on_draw( const Cairo::RefPtr<Cairo::Context>& cr ) override; 20 bool on_button_press_event( GdkEventButton* event ) override; 21 22 private: 23 void prepareProperties( ); 24 25 dataType< >& data_; 26 27 std::pair< 28 dataType< >::const_iterator, 29 dataType< >::const_iterator > minMaxPairForX0_, minMaxPairForX1_; 30 31 double width_, height_; 32 }; 33} 34#endif

試したこと

MyDrawingArea.cppを

bool MyDrawingArea::on_draw( const Cairo::RefPtr<Cairo::Context>& cr ){ if( 0 == data_.size( ) ) return false; auto x0band = (*minMaxPairForX0_.first).first - (*minMaxPairForX0_.second).first/1.2; auto x1band = (*minMaxPairForX1_.first).second - (*minMaxPairForX1_.second).second/1.2;
bool MyDrawingArea::on_button_press_event( GdkEventButton* event ){ if( 0 == data_.size( ) ) return false; prepareProperties( ); auto x0band = (*minMaxPairForX0_.first).first - (*minMaxPairForX0_.second).first/1.2; auto x1band = (*minMaxPairForX1_.first).second - (*minMaxPairForX1_.second).second/1.2;

に変更したところ,発生している問題と同様の状態になりました.
このような挙動をするように左側,下側へスケール変更が行われるようにしたいです.

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

開発は,統合開発環境のvscodeを用いており,cppは11を利用しています.

どうかご助力いただけると助かります.
おそらくMyDrawingArea.cppを変更すればいいと思うのですが...

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

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

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

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

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

yuki23

2018/09/18 10:27

GTK+ をタグに入れたほうがいいかもしれません
yoshiki0424yi

2018/09/18 13:23

承知しました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問