KubeRider :: Display pod info in a custom PyQt5 List Item
Published: 2019-11-24 13:05:01

---
title: KubeRider :: Display pod info in a custom PyQt5 List Item
published: true
date: 2019-07-28 15:10:17 UTC
tags: 
canonical_url: https://deskriders.dev/kuberider-copy/
---

 ![](https://deskriders.dev/media/posts/7/qdesigner_widget.png)

In this post, I'll go through the process of building a custom list widget in PyQt5 and using it to display Kubernetes pod information.

There are two different ways (AFAIK) to create a custom list item with PyQt5. Using [QListView](https://doc.qt.io/qt-5/qlistview.html) and [QListWidget](https://doc.qt.io/qt-5/qlistwidget.html). 

QListWidget is easy to use as you can build a widget using QDesigner and use it. QListView is more involved but it gives much more flexibility and better performance when dealing with a large number of items.

I decided to use QListWidget for now to quickly develop this proof of concept but considering that I may have to switch that out with QListView if performance becomes an issue.

Using QDesigner, here is a simple widget with some QLabels and organised in a simple layout.

![](https://deskriders.dev/media/posts/7/qdesigner_widget.png)

QDesigner generates a .ui file which can be converted to python using [pyuic5](https://www.riverbankcomputing.com/static/Docs/PyQt5/designer.html). I have a [simple script](https://github.com/namuan/kube-rider/blob/master/pre-build.sh) which processes all the [ui files](https://github.com/namuan/kube-rider/tree/master/resources/ui) and generates code in the [target folder](https://github.com/namuan/kube-rider/tree/master/kuberider/generated). 

```sh
for i in `ls resources/ui/*.ui`; do FNAME=`basename $i ".ui"`; ./venv/bin/pyuic5 $i \> "kuberider/generated/$FNAME.py"; done
```

Now the widget code is generated, the following class inherits from QWidget and the generated class to setup the widget UI. 

```python
from PyQt5 import QtWidgets

from ..entities.model import KubePodItem
from ..generated.pod_item_widget import Ui_PodItemWidget

class PodItemWidget(QtWidgets.QWidget, Ui_PodItemWidget):
 pod_info: KubePodItem

 def __init__(self, pod_info: KubePodItem, parent=None):
   super(PodItemWidget, self).__init__(parent)
   self.setupUi(self)
   self.set_data(pod_info)

 def set_data(self, pod_info: KubePodItem):
   self.pod_info = pod_info
   self.lbl_pod_name.setText(pod_info.name)
   self.lbl_pod_count.setText(pod_info.count)
   self.lbl_pod_status.setText(pod_info.pod_status)

 def get_data(self):
   return self.pod_info
```

Along with the code to setup the UI in the constructor, it also contains a couple of helper methods to update the data in the widget based on the [KubePodItem](https://github.com/namuan/kube-rider/blob/3014fed32049462de275dcadfa44701b6ce0df01/kuberider/entities/model.py#L54) object.

The only thing left now is to connect with the event notifying that pods have been loaded so that we can populate the list widget. See [this post](https://dev.to/namuan/kuberider-events-and-signals-with-pyqt5-3k8c) for how events and signals are used in this application.

```python
  def on_pods_loaded(self, pods):
   logging.info(f"on_pods_loaded: Displaying {len(pods)}")
   self.view.clear()
   for pod in pods:
     pod_widget = PodItemWidget(pod, self.view)
     pod_widget_item = QtWidgets.QListWidgetItem(self.view)
     pod_widget_item.setSizeHint(pod_widget.sizeHint())

     self.view.addItem(pod_widget_item)
     self.view.setItemWidget(pod_widget_item, pod_widget)
```

That should be it. Here is how it looks like with few pods. It shows the pod name, current status of the pod and number of containers ready.

![](https://deskriders.dev/media/posts/7/kube_rider_pods.gif)