Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What Qt widget(s) to use for read-only, scrollable, collapsible, icon list

I'm relatively new to Qt, and am not entirely familiar with the out-of-the-box widgets. I have a somewhat (but not very) complex widget to create, and don't want to reinvent any wheels. What is the best QWidget to use as a starting point to subclass and/or QWidgets to use to compose my widget. Here is the end-result I am looking for (apologies for the crude drawing):

Widget

Key points:

  • All icons will take up the same size, say 128 x 128. Ignoring the category groupings, they should all align in a nice grid.
  • The widget should expand to fill all the horizontal and vertical area it can take. Expanding / shrinking horizontally may increase / decrease the number of icons shown in each row.
  • Icons are grouped, and those groups should be collapsible.
  • If the height of the widget exceeds its space, a vertical scrollbar should appear.
like image 306
Dave Mateer Avatar asked Sep 03 '10 20:09

Dave Mateer


People also ask

How do I make my Qt widget scrollable?

You should create widget, fill it with proper layout and then use QScrollArea::setWidget(QWidget *) to make it scrollable.

What is QWidget in Qt?

Widgets are the primary elements for creating user interfaces in Qt. Widgets can display data and status information, receive user input, and provide a container for other widgets that should be grouped together. A widget that is not embedded in a parent widget is called a window.

What is QWidget parent?

The tree-like organization of QWidgets (and in fact of any QObjects ) is part of the memory management strategy used within the Qt-Framework. Assigning a QObject to a parent means that ownership of the child object is transferred to the parent object. If the parent is deleted, all its children are also deleted.


1 Answers

You're actually looking for some of the more esoteric options for a QListView/QListWidget.

At the top level, add QTreeWidget or QTreeView will give you the hierarchy you're looking for, as well as managing the scrolling area.

Each Listed Item of the (expanded) QTreeXItem will be a QListView/QListWidget, setting setViewMode(QListView::IconMode) on them.

EDIT: Note that to get the precise look you wanted above, you'll probably have to use QListView and use a custom delegate, handling the drawing yourself (unless you can find a theme that will do exactly what you want). However, I've coded up a short PyQt solution below using the Q*Widget classes because they're shorter, and will still demonstrate how to get the right layout. If you're using C++, the same Qt function calls apply, but obviously you might have more or less bookkeeping.

import sys
from PyQt4 import QtGui, QtCore

class displayItem(QtGui.QWidget):  #A simple widget to display, just centers a digit in a 100x100 widget
    def __init__(self,num):
        QtGui.QWidget.__init__(self)
        self.size=100
        self.resize(self.size,self.size)
        self.setMinimumSize(self.size,self.size)
        self.text = num
    def paintEvent(self,event):
        p = QtGui.QPainter(self)
        p.drawText(self.size//2,self.size//2,str(self.text))

app = QtGui.QApplication(sys.argv)
widget = QtGui.QTreeWidget()
widget.setWindowTitle('simple tree')

#Build the list widgets
treeItem1 = QtGui.QTreeWidgetItem(widget)
treeItem1.setText(0,"TreeWidget Parent")   #Sets the "header" for your [+] box

list1 = QtGui.QListWidget()                #This will contain your icon list
list1.setMovement(QtGui.QListView.Static)  #otherwise the icons are draggable
list1.setResizeMode(QtGui.QListView.Adjust) #Redo layout every time we resize
list1.setViewMode(QtGui.QListView.IconMode) #Layout left-to-right, not top-to-bottom

listItem = QtGui.QListWidgetItem(list1)
listItem.setSizeHint(QtCore.QSize(100,100)) #Or else the widget items will overlap (irritating bug)
list1.setItemWidget(listItem,displayItem(1))

listItem = QtGui.QListWidgetItem(list1)     #Add a few more items
listItem.setSizeHint(QtCore.QSize(100,100))
list1.setItemWidget(listItem,displayItem(2))

listItem = QtGui.QListWidgetItem(list1)
listItem.setSizeHint(QtCore.QSize(100,100))
list1.setItemWidget(listItem,displayItem(3))

list1.setAutoFillBackground(True)                #Required for a widget that will be a QTreeWidgetItem widget
treeSubItem1 = QtGui.QTreeWidgetItem(treeItem1)  #Make a subitem to hold our list
widget.setItemWidget(treeSubItem1,0,list1)       #Assign this list as a tree item

treeItem2 = QtGui.QTreeWidgetItem(widget)        #Make a fake second parent
treeItem2.setText(0,"TreeWidget Parent II")

widget.show()           #kick off the app in standard PyQt4 fashion
sys.exit(app.exec_())
like image 82
jkerian Avatar answered Sep 30 '22 00:09

jkerian