在PyQt5中创建复杂的自定义窗口小部件并将其添加到QGridlayout [英] Creating a complex custom widget in PyQt5 and adding it to a QGridlayout

查看:87
本文介绍了在PyQt5中创建复杂的自定义窗口小部件并将其添加到QGridlayout的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须创建一个类似于以下内容的自定义小部件:

I have to create a custom widget that looks like the following:

custom_widget_sketch

custom_widget_sketch

每个自定义窗口小部件代表一个LIPO电池,并显示电池电量(V),状态文本(充电,放电等),电池的序列号电池(S/N)和三个状态 LED (黄色,绿色和红色)

Each custom widget is a representation of one LIPO battery, and displays the battery volatge (V), status text (charging, discharging, etc), serial number of the battery (S/N) and three status LEDs (yellow, green and red)

创建自定义窗口小部件后,我需要在6 * 5的网格中添加其中的30个.我在这里的假设是,一旦创建了自定义小部件,它就应该像在QGridLayout中添加QPushButton这样简单:

After I have created the custom widget I need to add 30 of these in a grid of 6*5. My assumption here is that once I have created that custom widget it should be as simple as adding say a QPushButton in a QGridLayout like so:

custom_layput = QGridLayout()
custom_layout.addWidget(custom_widget, 0, 0)
custom_layout.addWidget(custom_widget, 0, 1)

.
.
.

custom_layout.addWidget(custom_widget, 6, 5)

最终屏幕如下所示:

main_window_sketch

main_window_sketch

考虑到所有这些要求,我有以下问题:

Considering all of these requirements I have the following questions:

  1. 我能够使用PyQt5创建如此复杂/丰富的自定义窗口小部件吗?可以吗?
  2. 这是创建自定义窗口小部件的正确方法吗:首先使用QPainter绘制一个正方形(这是custom_widget_sketch中的蓝色正方形),然后添加QLineEdits来显示电压(V)文本,序列号(S/N)文本和状态文本,添加一个QLabel以在自定义小部件中显示"V","S/N"和"STATUS"标签,然后绘制三个圆圈:每个分别代表黄色,绿色和红色的 LED,然后结合使用 QVBoxLayout 和QHBoxLayout来排列 QLineEdits QLabels ,正方形和圆形(LED指示器)
  3. 如何打包此自定义窗口小部件,以便像将 QPushButton QLineEdit 那样简单地将其添加到布局中?
  1. Will I able able to create such a complex/rich custom widget using PyQt5? Is it doable?
  2. Is this the correct approach to create the custom widget: first draw a square using QPainter (this is the blue square in the custom_widget_sketch), then add QLineEdits to dispaly the voltage (V) text, serial number (S/N) text and the Status text, add a QLabel for displaying the "V", "S/N" and "STATUS" labels in the custom widget, then draw the three circles: one each for the yellow, green and red LEDs, then use a combination of QVBoxLayout and QHBoxLayout to arrange the QLineEdits, QLabels, the square and the circles (LED indicators)
  3. How do I package this custom widget such that I can simply add it to a layout like I would add a QPushButton or a QLineEdit?

PS:custom_widget_sketch在左上角还包含一条线和一个正方形,其中三个线位于其中.这是用于描绘LIPO电池的连接器.现在实施起来可能太复杂了.因此,即使我能够实现除这两个元素以外的所有功能,我也会很高兴

PS: The custom_widget_sketch also contains a line and a square with three lines inside it in the top left corner. This is to depict the connector for the LIPO battery. It may be too complex to implement that right now. So I would be happy even if I am able to implement everything other than these two elements

我经历了一些SO问题,但是它们都涉及一个教程,这不是我的最终目标.

I have been through a few SO questions but they all refer to one tutorial, which is not my end goal.

我将不胜感激任何代码片段,要遵循的代码/步骤的一般概述,或链接到创建与我希望创建的自定义小部件相似的任何自定义小部件的文章/教程.

I would appreciate any code snippets, general outline of code/steps to follow or links to any articles/tutorials that create custom widgets similar to the one I wish to create.

推荐答案

我最终创建的自定义窗口小部件的Python代码.该小部件如下所示:

Python code for the custom widget I ended up creating. The widget looks as follows:

from PyQt5.QtGui import QPainter, QPen,QBrush,QColor
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout,QPushButton, QLineEdit, QLabel, QVBoxLayout, QHBoxLayout, QSizePolicy, QGroupBox
import sys

class BatteryStatusWidget(QWidget):
    def __init__(self):
        super(BatteryStatusWidget, self).__init__()
        #Voltage widgets
        self.voltage_text = QLineEdit()
        self.voltage_text.setReadOnly(True)
        self.voltage_label = QLabel("V")
        self.voltage_label.setStyleSheet("QLabel {color : white}")

        #Status widgets
        self.status_text = QLineEdit()
        self.status_text.setReadOnly(True)
        self.status_label = QLabel("STATUS")
        self.status_label_font = QtGui.QFont()
        self.status_label_font.setPointSize(12)
        self.status_label.setFont(self.status_label_font)
        self.status_label.setAlignment(QtCore.Qt.AlignCenter)
        self.status_label.setStyleSheet("QLabel {color : white}")

        #Serial number
        self.serial_number_text = QLineEdit()
        self.serial_number_label = QLabel("S/N")

        #LED widgets
        self.yellow_led_label = QLabel()
        self.yellow_led_label.setStyleSheet("QLabel {background-color : yellow; border-color : black; border-width : 1px; border-style : solid; border-radius : 10px; min-height: 20px; min-width: 20px}")
        self.green_led_label = QLabel()
        self.green_led_label.setStyleSheet("QLabel {background-color : green; border-color : black; border-width : 1px; border-style : solid; border-radius : 10px; min-height: 20px; min-width: 20px}")
        self.red_led_label = QLabel()
        self.red_led_label.setStyleSheet("QLabel {background-color : red; border-color : black; border-width : 1px; border-style : solid; border-radius : 10px; min-height: 20px; min-width: 20px}")

        #Number Identifier Label
        #This label is for tagging the widget with the same label as on the PCB
        self.number_label = QLabel("Test")
        self.number_label.setAlignment(QtCore.Qt.AlignCenter)
        self.number_label_font = QtGui.QFont()
        self.number_label_font.setPointSize(12)
        self.number_label_font.setBold(True)
        self.number_label.setFont(self.number_label_font)

        #Layouts
        #voltage layout
        self.voltage_layout = QHBoxLayout()
        self.voltage_layout.addWidget(self.voltage_text)
        self.voltage_layout.addWidget(self.voltage_label)

        #Serial number layout
        self.serial_num_layout = QHBoxLayout()
        self.serial_num_layout.addWidget(self.serial_number_label)
        self.serial_num_layout.addWidget(self.serial_number_text)

        #Voltage and status box layouts
        self.blue_container = QWidget()
        self.blue_container.setStyleSheet("background-color:rgb(77, 122, 194);")
        self.blue_box_layout = QVBoxLayout()
        self.blue_box_layout.addLayout(self.voltage_layout)
        self.blue_box_layout.addWidget(self.status_text)
        self.blue_box_layout.addWidget(self.status_label)
        self.blue_container.setLayout(self.blue_box_layout)


        #Blue box+ serial num layout
        self.non_led_layout = QVBoxLayout()
        #self.non_led_layout.addWidget(self.number_label)
        self.non_led_layout.addWidget(self.blue_container)
        self.non_led_layout.addLayout(self.serial_num_layout)

        #LED layout
        self.led_layout = QVBoxLayout()
        self.led_layout.addWidget(self.yellow_led_label)
        self.led_layout.addWidget(self.green_led_label)
        self.led_layout.addWidget(self.red_led_label)
        self.led_layout.addStretch(1)

        #Main Layout
        self.main_layout = QHBoxLayout()
        self.main_layout.addLayout(self.non_led_layout)
        self.main_layout.addLayout(self.led_layout)

        #Main group box
        self.main_group_box = QGroupBox()
        self.main_group_box.setStyleSheet("QGroupBox{font-size: 10px}")
        self.main_group_box.setTitle("Chan #")
        self.main_group_box.setLayout(self.main_layout)

        #Outer main layout to accomodate the group box
        self.outer_main_layout = QVBoxLayout()
        self.outer_main_layout.addWidget(self.main_group_box)

        #Set the main layout
        self.setLayout(self.outer_main_layout)
        self.setWindowTitle("Battery Widget")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = BatteryStatusWidget()
    main_window.show()
    app.exec_()

我能够轻松创建30个自定义窗口小部件实例,并将其添加到问题中发布的 QGridLayout 中.最终的GUI屏幕如下所示:

I was able to easily create 30 instances of the custom widget and add it to a QGridLayout as I posted in my question. The final GUI screen looks as follows:

这篇关于在PyQt5中创建复杂的自定义窗口小部件并将其添加到QGridlayout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆