Настройте QListWidgetItem с дополнительными данными для хранения. Как?

QListWidgetItem содержит 2 данных: значок и текст. И я хочу сохранить в нем еще одну QString. Как я могу сделать? Вот мой тестовый код. ListWidget ничего не отображает после вызова addItem.

И как я могу узнать, какой элемент нажат? Функция SLOT — это «void on_listWidget_itemClicked (элемент QListWidgetItem*)». Очевидно, что элемент параметра является родительским классом: 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);
}

person catinred    schedule 03.05.2011    source источник


Ответы (2)


QListWidgetItem имеет функции-члены

void QListWidgetItem::setData ( int role, const QVariant & value )

и

QVariant QListWidgetItem::data ( int role ) const

для хранения произвольных данных (включая QString). Установите role = Qt::UserRole (или любое большее значение).

person TonyK    schedule 04.05.2011

Для перемещения вверх и вниз по иерархии классов вы можете использовать приведения типов, в данном случае dynamic_cast:

dynamic_cast<QListWidgetItem*>( your_item )

Вы можете использовать это в качестве параметра для ваших сигналов и слотов. Это сообщит принимающей функции: «Эй, раньше это был указатель на QListWidgetItem, так что относитесь к нему так!»

А для отображения дополнительной информации вам следует рассмотреть возможность использования QTableWidget. Я думаю, что это соответствовало бы вашим требованиям, и вам не пришлось бы идти в обход по поводу «контрабандной» информации, как вы это сделали ;-)

Изменить:

В ответ на ваш комментарий:

Взгляните на QTableWidgetItem. Вы увидите, что QTableWidgetItem тоже может иметь значок :-) Итак, что вам нужно сделать, это разделить вашу информацию на несколько QTableWidgetItems. У вас есть пункт для значка, вкл для текста и еще один для другого текста и того, что вам нужно.

Теперь каждая строка — это то же самое, что и раньше, как один элемент в ListWidget. Теперь, как только пользователь щелкает где-либо, вы используете сигнал 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();
}

Это всего лишь простой пример, который я быстро написал... Конечно, есть лучшие способы сделать это, но, возможно, это поможет решить вашу проблему.

Пример реализации в песочнице

person Exa    schedule 03.05.2011
comment
Спасибо. Но QTableWidget не поддерживает IconMode. Я хочу отображать значки с именами ниже, при нажатии приложение может получить информацию об элементе, в моем случае IP. - person catinred; 03.05.2011