Personalizar qlistwidgetitem con datos adicionales para almacenar, ¿cómo?
-
28-10-2019 - |
Pregunta
El QListWidgetItem contiene 2 datos: icono y texto. Y quiero almacenar otro QString en él. ¿Como lo puedo hacer? Aquí está mi código de prueba. El ListWidget no muestra nada después de llamar a AddItem.
¿Y cómo puedo saber en qué artículo se hace clic? La función de la ranura es "void on_listwidget_itemClicked (qlistwidgetitem* item)". Obviamente, el elemento del parámetro es la clase principal: QListWidgetItem, no la subclase: 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);
}
Solución
QListWidgetItem
tiene funciones de miembros
void QListWidgetItem::setData ( int role, const QVariant & value )
y
QVariant QListWidgetItem::data ( int role ) const
para almacenar datos arbitrarios (incluidos QString
). Establecer role = Qt::UserRole
(o cualquier valor más alto).
Otros consejos
Para moverse hacia arriba y hacia abajo en la jerarquía de clases, puede usar elenco, en este caso Dynamic_cast:
dynamic_cast<QListWidgetItem*>( your_item )
Puede usar esto como su parámetro para sus señales y ranuras. Esto le dirá a la función de recepción "Hey, esto solía ser un puntero en un qlistwidgetitem, ¡así que trátelo así!"
Y para mostrar más información, debe considerar usar QtableWidget. Creo que eso se ajustaría a su requisito y no tendría que desviarme sobre la información de "contrabando" como lo hizo ;-)
Editar:
Como respuesta a su comentario:
Mira esto QtableWidgetItem. Verá que un QtableWidgetItem también puede tener un icono :-) Entonces, lo que necesita hacer es dividir su información en varios QtableWidgetItems. Tiene un elemento para el icono, encendido para el texto y otro para otro texto y lo que necesita.
Ahora todos fila es lo que tenía antes como un elemento en un listwidget. Ahora, tan pronto como el usuario hace clic en algún lugar, usa la señal cellClicked( int row, int column )
y row
te dice en qué fila se ha hecho clic. Ahora tiene la fila que se ha hecho clic y puede obtener la información que está buscando.
Digamos que el usuario hizo clic en la cuarta fila. Cada fila tiene columnas. La primera columna contiene el icono, la segunda columna contiene el nombre. Y ahora lo especial: la tercera columna contiene la IP, pero es oculto. Puedes hacerlo usando hideColumn( int column )
.
Fila 4: [Columna 0: icono | Columna 1: Nombre | Columna 2: (Oculta) IP
Entonces, cada vez que el usuario hace clic en una fila, solo busca la IP en la columna número 2.
Por supuesto, puede agregar tantas celdas como desee ... una que contenga la cadena con el nombre, otra con una descripción ... y digamos que la última columna es su columna oculta con la IP.
También puede hacer que la cuadrícula sea invisible usando setShowGrid( false )
. Ahora parece una visualización normal de información, donde cada fila es un elemento.
:-)
Editar 2:
Para mostrarle lo que quiero decir, implementé un pequeño ejemplo. Vea el código a continuación.
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)) );
Ahora tenemos una mesa sin cuadrícula con encabezados horizontales (que no necesitas, por supuesto). Al hacer clic en una fila, se selecciona toda la fila y se llama la siguiente ranura:
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();
}
Este es solo un ejemplo simple que escribí rápidamente ... Hay mejores formas de hacerlo, por supuesto, pero tal vez ayude a resolver su problema.