自定义 QListWidgetItem 并存储额外的数据,如何?

发布于 2024-11-05 08:47:16 字数 839 浏览 2 评论 0原文

QListWidgetItem包含2个数据:图标和文本。我想在其中存储另一个 QString。我该怎么办?这是我的测试代码。在我调用 addItem 后,ListWidget 不显示任何内容。

我怎样才能知道哪个项目被点击了? SLOT 函数是“void on_listWidget_itemClicked(QListWidgetItem* item)”。显然参数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);
}

The QListWidgetItem contains 2 data: icon and text. And I want to store another QString in it. How can I do? Here is my test code.The ListWidget displays nothing after I call addItem.

And how can I know which item is clicked? The SLOT function is "void on_listWidget_itemClicked(QListWidgetItem* item)". Obviously the parameter item is the parent class: QListWidgetItem, NOT the subclass: 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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

似最初 2024-11-12 08:47:16

QListWidgetItem 具有成员函数

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

QVariant QListWidgetItem::data ( int role ) const

用于存储任意数据(包括QString)。设置role = Qt::UserRole(或任何更高的值)。

QListWidgetItem has member functions

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

and

QVariant QListWidgetItem::data ( int role ) const

for storing arbitrary data (including QString). Set role = Qt::UserRole (or any higher value).

坚持沉默 2024-11-12 08:47:16

要在类层次结构中上下移动,您可以使用强制转换,在本例中为dynamic_cast:

dynamic_cast<QListWidgetItem*>( your_item )

您可以使用它作为信号和槽的参数。这将告诉接收函数“嘿,这曾经是 QListWidgetItem 上的指针,所以就这样对待它!”

为了显示更多信息,您应该考虑使用 QTableWidget。我认为这符合您的要求,您不必像您那样绕道“走私”信息;-)

编辑:

作为对您评论的回应:

看看QTableWidgetItem。您将看到,QTableWidgetItem 也可以有一个图标:-) 所以您需要做的是将您的信息分成几个 QTableWidgetItem。您有一个用于图标的项目,一个用于文本的项目,还有另一个用于另一个文本和您需要的内容的项目。

现在,每一行都是您之前在 ListWidget 中作为一项的内容。现在,只要用户单击某处,您就可以使用信号 cellClicked( int row, int column ) ,并且 row 告诉您单击了哪一行。现在您已经获得了已单击的行,并且可以获取您要查找的信息。

假设用户单击了第四行。每行都有列。第一列包含图标,第二列包含名称。现在有一个特别的事情:第三列包含 IP,但隐藏。您可以使用 hideColumn( int column ) 来执行此操作。

第 4 行:[ 第 0 列:图标 |第 1 栏:姓名 |第 2 列:(隐藏)IP ]

因此,每次用户单击一行时,您只需在第 2 列中查找 IP。

当然,您可以添加任意数量的单元格...一个包含带有名称的字符串,另一个包含带有描述的...我们可以这么说,最后一列是包含 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();
}

这只是我快速编写的一个简单示例...当然有更好的方法可以做到这一点,但也许它有助于解决您的问题。

沙箱应用程序中的示例实现

For moving up and down in the class hierarchy you can use casts, in this case dynamic_cast:

dynamic_cast<QListWidgetItem*>( your_item )

You can use this as your parameter for your signals and slots. This will tell the recieving function "Hey, this used to be a pointer on a QListWidgetItem, so treat it like that!"

And for displaying more information you should consider using QTableWidget instead. I think that would fit your requirement and you would not have to go that detour over "smuggling" information like you did ;-)

Edit:

As a response to your comment:

Have a look at QTableWidgetItem. You will see, that a QTableWidgetItem can have an icon too :-) So what you need do is, split your information into several QTableWidgetItems. You have an item for the icon, on for the text, and another one for another text and what you need.

Now every row is what you had before as one item in a ListWidget. Now as soon as the user clicks somewhere, you use the signal cellClicked( int row, int column ) and row tells you which row has been clicked. Now you have the row that has been clicked and can get the information you're looking for.

Lets say the user clicked the 4th row. Each row has columns. The first column contains the icon, the second column contains the name. And now the special thing: The third column contains the IP, but is hidden. You can do so, by using hideColumn( int column ).

Row 4: [ Column 0: Icon | Column 1: Name | Column 2: (hidden) IP ]

So everytime the user clicks a row, you just look up the IP in column number 2.

Of course you can add as much cells as you want... One containing the string with the name, another one with a description... And let's just say, the last column is your hidden column with the IP.

You can also make the grid invisible by using setShowGrid( false ). Now it looks like a normal display of information, where every row is one item.

:-)

Edit 2:

To show you what I mean I implemented a small example. See the code below.

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)) );

Now we have a table without grid with horizontal headers (which you dont need of course). When clicking on a row, the whole row is selected and the following slot is called:

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();
}

This is just a simple example I quickly wrote... There are better ways of doing this of course, but maybe it helps to solve your problem.

Example implementation in sandbox app

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文