Qt Application Custom Widgets and Dialogs Templates (No .ui File)

UI Module without .ui file

There is a different between inheriting from QWidget class vs QMainWindow

Inheriting from QWidget:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class InheritQWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(InheritQWidget, self).__init__(parent)

# initialization object
layout = QtWidgets.QGridLayout()
listWidget = QtWidgets.QListWidget()
#treeWidget = QtWidgets.QTreeWidget()

# set
# treeWidget.setParent(listWidget)
layout.addWidget(listWidget)
self.setLayout(layout)

listWidget.addItem('item A')
listWidget.addItem('item B')

Inheriting from QMainWindow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class InheritQMainWindow(QtWidgets.QMainWindow):
# Window inherits from QMainWindow the layout is already defined
# to accommodate any toolbars or any other QMainWindow component
# use the setCentralWidget() to accommodate this

def __init__(self, parent=None):
super(InheritQMainWindow, self).__init__(parent)

# initialization object
widget = QtWidgets.QWidget()
layout = QtWidgets.QGridLayout()

# set
self.setCentralWidget(widget)
widget.setLayout(layout)

label = QtWidgets.QLabel('test')
layout.addWidget(label, 0, 0)

Custom Dialog

Sometimes we need a quick window to display some information, but the built-in qt message boxes aren’t suitable for the job.


Custom Widget

We can choose to create a widget class, but also for saving time, we can create a temporary custom widget

example:

Couple of things worth noting:

  1. correctly initialize the widget

    self.customWidget = QtWidgets.QWidget() will allow widget be child of the main window, thus allow widget to close when main window is closed

    so not customWidget = QtWidgets.QWidget() or self.customWidget = QtWidgets.QWidget(self)

  2. use getattr in combination with QStyle and name of the built-in icon

  3. use win.setAttribute(QtCore.Qt.WA_DeleteOnClose) to make sure the child widget is killed after main window is closed, because default close only hides window objects

  4. self.customWidget.show() is the core command to call it to display

Custom QMessageBox

add custom buttons to the QMessageBox layout

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dialog = QtWidgets.QMessageBox()
dialog.setText("Overwrite?")
dialog.setIcon(QtWidgets.QMessageBox.Critical)

yes_btn = dialog.addButton("Yes!", QtWidgets.QMessageBox.YesRole)
no_btn = dialog.addButton("No", QtWidgets.QMessageBox.NoRole)
abort_btn = dialog.addButton("Abort", QtWidgets.QMessageBox.RejectRole)
dialog.exec_()

if dialog.clickedButton() == yes_btn:
print("yes")
elif dialog.clickedButton() == no_btn:
print("no")
elif dialog.clickedButton() == abort_btn:
print("abort")

Don’t use the return value of QMessageBox::exec, as it only makes sense for standard buttons. Also don’t rely on buttonRole as multiple buttons could be sharing the same role.

Reference

Programiz - Python getattr()

GUIS - Q&A: Are there any built-in QIcons?