TextView内のカーソルの位置(何行、何文字目)を取得する

概要

TextBuffer内の文字は Gtk::TextBuffer::iterator オブジェクトによって表されるので、カーソル位置を 得るにはカーソル位置のiteratorを取得する必要がある。ただしカーソル位置はiteratorではなくて Gtk::TextBuffer::Markオブジェクトで与えられているので、Gtk::TextBuffer::Mark::get_iter() によってカーソル位置の iteratorを取得する。具体的には次のようにする。

Gtk::TextView m_textview;
m_textview.get_buffer()->get_insert()->get_iter();

あとは Gtk::TextBuffer::iterator::get_line()とGtk::TextBuffer::iterator::get_line_offset() で カーソルの位置を取得できる。ここでget_line_offset()はバイトではなくてユニコード文字として カウントされるのに注意する。つまり日本語の文字の場合は3文字ではなくて1文字でカウントされる。 またget_line()とget_line_offset()は0から始まることに注意する。

ソース

textview2.cpp
#include <gtkmm.h>
#include <iostream>

class MainWin : public Gtk::Window
{
    Gtk::TextView m_textview;

public:
    MainWin();
    virtual ~MainWin();

private:
    void on_buf_changed();
};

MainWin::MainWin()
{
    // バッファ更新シグナル
    m_textview.get_buffer()->signal_changed().connect( sigc::mem_fun( *this, &MainWin::on_buf_changed ) );

    add( m_textview );
    show_all_children();

    resize( 600,600 );
}

MainWin::~MainWin()
{}


void MainWin::on_buf_changed()
{
    std::cout << "---------------------\n" << m_textview.get_buffer()->get_text() << std::endl
              << "何行目   = " << m_textview.get_buffer()->get_insert()->get_iter().get_line() << std::endl
              << "何文字目 = " << m_textview.get_buffer()->get_insert()->get_iter().get_line_offset() << std::endl;
}


int main( int argc, char *argv[] )
{
    Gtk::Main kit( argc, argv );
    MainWin mainwin;
    Gtk::Main::run( mainwin );

    return 0;
}

コンパイル

必要なコンパイルオプションは pkg-config を使って取得する。

g++ textview2.cpp -o textview2 `pkg-config gtkmm-2.4 --cflags --libs`

結果

文字を入力するとコンソールにカーソルの現在位置が表示される。