Gtk::TextView с постоянной строкой

Я использую Gtkmm 3+, и я пытаюсь сделать так, чтобы текстовый буфер имел постоянную строку «>», даже если пользователь пытается ее удалить. Кроме того, когда пользователь нажимает клавишу возврата, он автоматически снова оказывается там. В основном есть постоянная строка, как в терминале.

Единственный способ, которым я могу думать о выполнении этого, - это подключиться к сигналам удаления и возврата, чтобы пользователь не мог удалить строку. Но есть ли лучший способ?

пока это единственный способ, о котором я могу думать:

//in constructor
txt_view_i_.signal_event().connect(sigc::mem_fun(*this, &MainWindow::inputEvent));

//function
bool MainWindow::inputEvent(GdkEvent* event)
{
    if((event->key.keyval == GDK_KEY_BackSpace || event->key.keyval == GDK_KEY_Delete) && buffer_input_->get_char_count() < 3)
        return true;

    return false;
}

Но работает не идеально, потому что, если вы введете более 3 символов, а затем перейдете к началу строки, вы можете удалить постоянную строку.

Еще один способ, о котором я только что подумал, — это добавить метку к виджету TextView. Я сделал это, но пользователь все еще мог удалить его. Вот код для этого:

Gtk::TextBuffer::iterator it = buffer_input_->get_iter_at_line(1);
Glib::RefPtr<Gtk::TextChildAnchor> refAnchor = buffer_input_->create_child_anchor(it);
Gtk::Label* lbl = Gtk::manage(new Gtk::Label("> "));
txt_view_i_.add_child_at_anchor(*lbl, refAnchor);

person vis.15    schedule 04.12.2013    source источник


Ответы (2)


Это очень похоже, но не совсем идентично вопросу, на который я ответил здесь: вы можете создать GtkTextTag, который сделает его содержимое нередактируемым, и применить его от начала буфера до приглашения "> " включительно.

Затем, когда вы получаете ввод, добавьте свой вывод в буфер, а затем добавьте новое приглашение в следующей строке и повторно примените тег, чтобы сделать все это нередактируемым.

Ссылки в связанном ответе показывают некоторый код C, где это делается, даже включая подсказку. Это не Gtkmm или C++, но это должно служить иллюстрацией.

person ptomato    schedule 04.12.2013

Вот код, который я использовал для его решения:

Glib::RefPtr<Gtk::TextBuffer::Tag> tag = Gtk::TextBuffer::Tag::create();
tag->property_editable() = false;
Glib::RefPtr<Gtk::TextBuffer::TagTable> tag_table =  Gtk::TextBuffer::TagTable::create();
tag_table->add(tag);
buffer_input_ = Gtk::TextBuffer::create(tag_table);
txt_view_i_.set_buffer(buffer_input_);
scroll_win_i_.add(txt_view_i_);

Gtk::TextBuffer::iterator buffer_it_ = buffer_input_->begin();
buffer_input_->insert_with_tag(buffer_it_, "> ", tag);

Вот как я сделал так, чтобы пользователь не мог редактировать перед константной строкой:

//connect to the mark set signal
buffer_input_->signal_mark_set().connect(sigc::mem_fun(*this, &MainWindow::setMark));

//make the box uneditable
void MainWindow::setMark(const Gtk::TextBuffer::iterator& it, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark)
{
    if(it.get_offset() < 2)
        txt_view_i_.set_editable(false);
    else
        txt_view_i_.set_editable(true);
}

Надеюсь, кто-то найдет это полезным.

person vis.15    schedule 04.12.2013