Настройте QListWidgetItem с дополнительными данными для хранения, как?
-
28-10-2019 - |
Вопрос
QlistWidgetItem содержит 2 данные: значок и текст. И я хочу хранить в нем еще один QString. Как я могу сделать? Вот мой тестовый код. ListWidget ничего не отображает после того, как я вызову Additem.
И как я могу узнать, какой элемент щелкнут? Функция слота - «void on_listwidget_itemclicked (qlistwidgetitem* item)». Очевидно, что элемент параметра является родительским классом: QlistWidgetItem, а не подкласс: ListWidgetItem
ListWidgetItem::ListWidgetItem(const QIcon &icon, const QString &text,QString &ip, QListWidget *parent, int type)
{
myip = ip;
QListWidgetItem::QListWidgetItem(icon,text,parent,type);
}
ListWidgetItem::~ListWidgetItem()
{
}
QVariant ListWidgetItem::data(int role) const
{
if (role==IPROLE)
{
return myip;
}
return QListWidgetItem::data(role);
}
void ListWidgetItem::setData(int role, const QVariant &value)
{
if (role==IPROLE)
{
myip = value.toString();
}
QListWidgetItem::setData(role,value);
}
Решение
QListWidgetItem
имеет функции участников
void QListWidgetItem::setData ( int role, const QVariant & value )
а также
QVariant QListWidgetItem::data ( int role ) const
для хранения произвольных данных (включая QString
) Установлен role = Qt::UserRole
(или любое более высокое значение).
Другие советы
Для движения вверх и вниз в иерархии классов вы можете использовать Casts, в данном случае Dynamic_CASC:
dynamic_cast<QListWidgetItem*>( your_item )
Вы можете использовать это в качестве параметра для ваших сигналов и слотов. Это сообщит об определении функции: «Эй, это было указатель на QlistWidgetItem, так что относитесь к ней так!»
И для отображения дополнительной информации вы должны рассмотреть вопрос о использовании QtableWidget вместо этого. Я думаю, что это соответствовало бы вашим требованиям, и вам не придется идти в то время как «контрабанда», как вы, ;-)
Редактировать:
В ответ на ваш комментарий:
Посмотри на QtableWidgetItem. Анкет Вы увидите, что QtableWidgetItem тоже может иметь значок :-) Так что вам нужно сделать, разделите вашу информацию на несколько QTableWidgetItems. У вас есть элемент для значка, для текста, и другой для другого текста и того, что вам нужно.
Теперь каждый строка это то, что вы имели раньше как один элемент в спискевиджере. Теперь, как только пользователь где -то нажимает, вы используете сигнал cellClicked( int row, int column )
а также row
Рассказывает, какая строка была нажата. Теперь у вас есть ряд, который был нажат и может получить информацию, которую вы ищете.
Допустим, пользователь щелкнул 4 -й ряд. Каждая строка имеет столбцы. Первый столбец содержит значок, второй столбец содержит имя. А теперь особенная вещь: третий столбец содержит IP, но скрытый. Анкет Вы можете сделать это, используя hideColumn( int column )
.
Строка 4: [столбец 0: значок | Столбец 1: Имя | Столбец 2: (скрытый) IP
Поэтому каждый раз, когда пользователь нажимает строку, вы просто смотрите IP в столбце № 2.
Конечно, вы можете добавить столько ячеек, сколько хотите ... одна, содержащая строку с именем, еще один с описанием ... и, давайте просто скажем, последний столбец - ваш скрытый столбец с IP.
Вы также можете сделать сетку невидимой, используя setShowGrid( false )
. Анкет Теперь это выглядит как обычный отображение информации, где каждая строка является одним из пунктов.
:-)
РЕДАКТИРОВАТЬ 2:
Чтобы показать вам, что я имею в виду, я реализовал небольшой пример. Смотрите код ниже.
m_table_widget = new QTableWidget( 4, 4, this );
QTableWidgetItem* my_item_0 = new QTableWidgetItem( "icon 1" );
QTableWidgetItem* my_item_1 = new QTableWidgetItem( "server 1" );
QTableWidgetItem* my_item_2 = new QTableWidgetItem( "this is server 1" );
QTableWidgetItem* my_item_3 = new QTableWidgetItem( "192.0.0.1" );
QTableWidgetItem* my_item_4 = new QTableWidgetItem( "icon 2" );
QTableWidgetItem* my_item_5 = new QTableWidgetItem( "server 2" );
QTableWidgetItem* my_item_6 = new QTableWidgetItem( "this is server 2" );
QTableWidgetItem* my_item_7 = new QTableWidgetItem( "192.0.0.2" );
m_table_widget->setItem( 0, 0, my_item_0 );
m_table_widget->setItem( 0, 1, my_item_1 );
m_table_widget->setItem( 0, 2, my_item_2 );
m_table_widget->setItem( 0, 3, my_item_3 );
m_table_widget->setItem( 1, 0, my_item_4 );
m_table_widget->setItem( 1, 1, my_item_5 );
m_table_widget->setItem( 1, 2, my_item_6 );
m_table_widget->setItem( 1, 3, my_item_7 );
m_table_widget->hideColumn( 3 );
m_table_widget->setShowGrid( false );
m_table_widget->setSelectionBehavior( QAbstractItemView::SelectRows );
m_table_widget->verticalHeader()->hide();
QStringList list;
list << "Icon" << "Name" << "Description" << "IP";
m_table_widget->setHorizontalHeaderLabels( list );
connect( m_table_widget, SIGNAL(cellClicked(int,int)), this, SLOT(on_cell_clicked(int,int)) );
Теперь у нас есть стол без сетки с горизонтальными заголовками (которые вам, конечно, не нужно). При нажатии на строку выбирается вся строка, и следующий слот называется:
void main_window::on_cell_clicked( int row, int column )
{
QString ip = m_table_widget->item( row, 3 )->text();
QMessageBox message( QMessageBox::Information, "Server Info", QString( "This is row %1 and the IP is: %2" ).arg( row ).arg( ip ) );
message.exec();
}
Это просто простой пример, который я быстро написал ... есть лучшие способы сделать это, конечно, но, возможно, это помогает решить вашу проблему.