Я использую gtkmm v3.22.
У меня есть ListBox
, который содержит ListBoxRows
, который я могу выбрать (для правильной оценки я использую SELECTION_MULTIPLE
). Я пытаюсь отменить выбор некоторых выбранных элементов, щелкая по ним, используя on_button_release_event
, но не могу заставить его работать. Вот код:
//=======================================================
// Adapted from GTKMM3/C++11 ListBox Example / W.Moore
// https://stackoverflow.com/questions/34253297/how-to-add-text-box-in-gtkmmgtklistbox-using-c/41388444#41388444
//=======================================================
#include <gtkmm.h>
#include <iostream>
#include <string>
#include <initializer_list>
#include <stdio.h>
using namespace std;
class MyListRow;
//======================================================
// My List Box
//======================================================
class MyListBox : public Gtk::ListBox
{
public:
MyListBox();
MyListBox(initializer_list<string> list);
void api_AddRow(string line);
void print(MyListRow *p);
void on_row_selected (MyListRow *p)
{
print(p);
}
protected:
void on_row_selected(Gtk::ListBoxRow *p)
{
on_row_selected((MyListRow*)p);
}
};
//======================================================
// My List Row
//======================================================
class MyListRow : public Gtk::ListBoxRow
{
public:
MyListRow(const string text)
: label{text}
{
add_events(Gdk::BUTTON_RELEASE_MASK);
add(label);
set_halign(Gtk::Align::ALIGN_START);
label.set_size_request(150);
show_all_children();
}
bool on_button_release_event (GdkEventButton* release_event)
{
if (release_event->button==1 && is_selected()) {
get_parent()->unselect_row(this);
return true;
} else
return false;
if (release_event->button==1 && is_selected()) {
get_parent()->unselect_row(this);
return true;
} else
return false;
}
void print()
{
printf("Selected %s\n", label.get_text().c_str());
}
protected:
Gtk::Label label;
inline MyListBox *get_parent() {
return (MyListBox*)ListBoxRow::get_parent();
}
};
void MyListBox::print(MyListRow *p)
{
p->print();
}
inline MyListBox::MyListBox()
{
set_selection_mode(Gtk::SELECTION_MULTIPLE);
show_all_children();
}
inline MyListBox::MyListBox(initializer_list<string> list)
{
set_selection_mode(Gtk::SELECTION_MULTIPLE);
for (auto s : list) {
api_AddRow(s);
}
}
inline void MyListBox::api_AddRow(string text)
{
auto row = Gtk::manage(new MyListRow{text});
append(*row);
row->show();
}
//======================================================
// My Window
//======================================================
class MyWindow : public Gtk::Window {
public:
MyWindow();
protected:
MyListBox listbox1 {
"List Item 1",
"List Item 2",
"List Item 3",
"List Item 4",
"List Item 5",
"List Item 6",
"List Item 7"
};
};
inline MyWindow::MyWindow() {
add(listbox1);
set_title("ListBox Example");
set_border_width(6);
set_default_size(300, 100);
show_all_children();
}
//======================================================
// Main
//======================================================
int main(int argc, char** argv) {
auto appMain = Gtk::Application::create(argc, argv, "org.gtkmm.example");
MyWindow MyWindow1;
appMain->run(MyWindow1);
return 0;
}
Чтобы увидеть, что происходит, запустите его под GDB и установите точку останова на Gtk::Widget::on_button_release_event
. Это покажет, что событие отпускания кнопки передается в Listbox
, тогда как предполагалось, что оно было первоначально передано в ListBoxRow
(если строка уже была выбрана, она вернула бы true и распространение не продолжалось бы дальше). [Дальнейшая точка останова на линии print(p)
в MyListBox
позволит вам увидеть адрес MyListBox
.]
Что я делаю не так?