背景:
项目需要,界面上显示10个相同设备信息,每个设备:包括一个按钮2个Label,每个设备有自己的线程。 希望单个设备界面及对应线程封闭,然后用for循环动态生成。
以下是解决界面的自定view: 用一个QWidget:里面添加Gridlayout,再往Grid里添加2label,1Button.
上效果图:
源码实现:
创建一个自定义一个QWidget类
难点就在这里,如摆放里面添加2个Label,一个Button,并显示紧凑。
CustomWidgetWithLayout.py
from PyQt5 import QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class T0DeviceWindow(QWidget):
def __init__(self, parent=None,index=0):
super(T0DeviceWindow, self).__init__(parent)
self.resize(60, 30)
self.layout=QtWidgets.QGridLayout()
self.layout.setContentsMargins(10, 0, 0, 0)
self.layout.setSpacing(1)
# 添加自定义部件(MyWidget)
# self.widget = MyWidget()
self.ll=QLabel(self)
self.ll.setText("L")
self.ll.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
self.ll.setFixedSize(10,30)
self.Rl=QLabel(self)
self.Rl.setText("R")
self.Rl.setFixedSize(10,30)
self.ll.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
self.deviceIndex=index
self.btn=QtWidgets.QPushButton(str(self.deviceIndex))
# 把按钮跟Label放入布局内
self.layout.addWidget(self.ll,0,0)
self.layout.addWidget(self.btn,0,1)
self.layout.addWidget(self.Rl,0,2)
self.setLayout(self.layout)
self.setWindowTitle("QWidget的自定义类")
主界面:
用.ui文件 生成比较简单,可以自己去拉一个。
BaseUi.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'BaseUi.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(597, 577)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 0, 571, 521))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.groupBox = QtWidgets.QGroupBox(self.verticalLayoutWidget)
self.groupBox.setEnabled(True)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
self.groupBox.setSizePolicy(sizePolicy)
self.groupBox.setObjectName("groupBox")
self.gridLayoutWidget = QtWidgets.QWidget(self.groupBox)
self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 10, 561, 331))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.radioButton = QtWidgets.QRadioButton(self.groupBox)
self.radioButton.setGeometry(QtCore.QRect(10, 20, 98, 21))
self.radioButton.setText("")
self.radioButton.setObjectName("radioButton")
self.horizontalLayoutWidget = QtWidgets.QWidget(self.groupBox)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(18, 350, 391, 80))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.pushButton_3 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.pushButton_3.setObjectName("pushButton_3")
self.horizontalLayout.addWidget(self.pushButton_3)
self.pushButton_2 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout.addWidget(self.pushButton_2)
self.verticalLayout.addWidget(self.groupBox)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 597, 25))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.groupBox.setTitle(_translate("MainWindow", "Devices"))
self.pushButton.setText(_translate("MainWindow", "Start"))
self.pushButton_3.setText(_translate("MainWindow", "Stop"))
self.pushButton_2.setText(_translate("MainWindow", "Pause"))
主函数:
这个比较简单,设置要显示多少个自定义QWidget: self.max_io_num = 10, 然后布成几列:max_io_display_cols, 再用一个for循环往主界面的Grid添加即可
from PyQt5 import QtCore
from PyQt5.QtWidgets import QMainWindow
from BaseUi import Ui_MainWindow
from CustomWidgetWithLayout import T0DeviceWindow
"""
设备,UI及对应的线程封装对象列表, 每个key-value对应一个设备,及显示的UI
"""
deviceUiList = {}
class MainWindows(Ui_MainWindow, QMainWindow):
def __init__(self, parent=None):
super(MainWindows, self).__init__(parent)
self.setupUi(self)
self.max_io_display_cols = 3
self.max_io_num = 10 # 动态生成的自定义QWidget个
self._initWidget()
self._initConnect()
def _initWidget(self):
pass
def _initConnect(self):
# self.pushButton_set.clicked.connect(self.onDisplayButtons)
self.onDisplayButtons()
def onDisplayButtons(self):
# self.max_io_display_cols = 2
# self.max_io_num = 2
print(self.max_io_display_cols, self.max_io_num)
self.addButtons()
def addButtons(self):
# self.removeButtons()
for i in range(self.max_io_num): # 动态添加到UI
io_control_btn = T0DeviceWindow(index=i)
self.gridLayout.setGeometry(QtCore.QRect(0,0,200,200))
self.gridLayout.addWidget(
io_control_btn,
int(i / self.max_io_display_cols),
int(i % self.max_io_display_cols + 1), 1, 1)
deviceUiList[i] = io_control_btn
print(deviceUiList)
def removeButtons(self):
while self.gridLayout.count():
item = self.gridLayout.takeAt(0)
widget = item.widget()
widget.deleteLater()
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
window = MainWindows()
window.show()
sys.exit(app.exec_())
以上是完成基本动态创建自定义view,后续会往QWidget视图添加点击事件,跟线程控制,基本上实现项目需要。