問題描述
我必須創建一個如下所示的自定義小部件:
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:
- 我能否使用 PyQt5 創建如此復雜/豐富的自定義小部件?可行嗎?
- 這是創建自定義小部件的正確方法嗎:首先使用 QPainter 繪制一個正方形(這是 custom_widget_sketch 中的藍色正方形),然后添加 QLineEdits 以顯示電壓 (V) 文本、序列號 (S/N)文本和狀態文本,添加一個 QLabel 用于在自定義小部件中顯示V"、S/N"和STATUS"標簽,然后繪制三個圓圈:黃色、綠色和紅色
LED 各一個
,然后使用QVBoxLayout
和 QHBoxLayout 的組合來排列QLineEdits
、QLabels
、正方形和圓形(LED 指示燈) - 如何打包這個自定義小部件,以便我可以像添加
QPushButton
或QLineEdit
一樣簡單地將其添加到布局中?
- Will I able able to create such a complex/rich custom widget using PyQt5? Is it doable?
- 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 ofQVBoxLayout
and QHBoxLayout to arrange theQLineEdits
,QLabels
, the square and the circles (LED indicators) - How do I package this custom widget such that I can simply add it to a layout like I would add a
QPushButton
or aQLineEdit
?
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的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!