The code:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import*
from PyQt5.QtGui import*
from PyQt5 import QtGui
from PyQt5.QtPrintSupport import *
class Pencere(QWidget):
def __init__(self):
super().__init__()
self.setGeometry(100,50,1080,1080)
self.setWindowIcon(QtGui.QIcon("note.png"))
self.setWindowTitle("M Content Re-Writer")
self.widget = QWidget(self)
self.widget.setObjectName("widget")
self.texteditor()
vbox2 = QVBoxLayout(self.widget)
vbox2.addWidget(self.button, alignment=Qt.AlignLeft)
vbox2.addWidget(self.editor, alignment=Qt.AlignLeft | Qt.AlignTop)
vbox = QVBoxLayout(self)
vbox.setContentsMargins(0, 0, 0, 0)
vbox.addWidget(self.widget)
def texteditor(self):
self.editor = QTextEdit()
self.editor.resize(500, 500)
self.editor.move(5,40)
self.button = QPushButton("re-write")
self.button.setFont(QFont('Segoe Script', 11))
self.button.setStyleSheet("border : 2px lemonchiffon; border-style : solid")
self.button.clicked.connect(self.function)
def function(self):
text = self.editor.toPlainText() # editor'de yazan yaziyi al
# path, _ = QFileDialog.getSaveFileName(self, "Save File", "", "Text documents (*.txt);All files (*.*)")
if not text: # == "":
print("none")
return
# else:
path, _ = QFileDialog.getSaveFileName(
self,
"Save file",
"",
"Text documents (*.txt);All files (*.*)")
if path:
with open(path, 'w') as murti:
murti.write(text)
qss = """
#widget {
border-image: url(2.jpg) 0 0 0 0 stretch stretch;
}
QPushButton {background-color : yellow;}
QPushButton:hover:pressed {background-color: red;}
QPushButton:hover {background-color: #0ff;}
QTextEdit {
background-image: url("hand.jpeg");
min-width: 400px;
min-height: 400px;
border: 2px solid black;
color:white;
font-size:24px;
}
"""
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyleSheet(qss)
demo = Pencere()
demo.show()
sys.exit(app.exec_())
Hello, How can I make the background of the title of the GUI window appear transparent instead of white? In addition, I want to ask this: How can I change the color and font style of the M Content Re-Writer text in the title? I also added a screenshot to make it better. Thanks for your help.
Since you are modifying the window title so much, I believe it would be helpful to simply remove it create a custom one.
self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint)
This code gets rid of the window frame (which removes the title bar.)
Now, we just need to create our own title bar. This will look something like:
self.topMenu = QLabel(self)
self.topMenu.setGeometry(0, 0, 1920, 60)
self.topMenu.setStyleSheet("background-color: rgba(255,255,255, 120);")
This code creates a blank bar for everything to rest on.
From here, you just need to create a label for text, followed by three buttons for closing, minimizing, and full screening the window.
Related
I want to change the color of selected item in QListItem, and I find qss may be a solution. And the code is:
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
with open('mainStyle.qss', 'r', encoding='utf-8') as file:
self.setStyleSheet(file.read())
# self.setStyleSheet('*{font-size: 15px;background-color: rgb(150, 150, 150);}'
# 'QListWidget::item:selected{background: rgb(128,128,255);}')
self.setStyleSheet('QListWidget::item:selected{background: rgb(128,128,255);}')
layout = QVBoxLayout()
self.setLayout(layout)
listWidget = QListWidget()
layout.addWidget(listWidget)
w1 = QWidget()
w1Item = QListWidgetItem()
w1Item.setSizeHint(QSize(150, 150))
listWidget.insertItem(0, w1Item)
listWidget.setItemWidget(w1Item, w1)
w2 = QWidget()
w2Item = QListWidgetItem()
w2Item.setSizeHint(QSize(150, 150))
listWidget.insertItem(1, w2Item)
listWidget.setItemWidget(w2Item, w2)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
win.show()
app.exec_()
We can see that the color is changed to be blue when the item is selected.
However, I need to provide a general background color for other widgets. So I change the style from
self.setStyleSheet('QListWidget::item:selected{background: rgb(0,0,255);}')
to
self.setStyleSheet('*{font-size: 15px;background-color: rgb(150, 150, 150);}'
'QListWidget::item:selected{background: rgb(0,0,0);}')
Then, I find QListWidget::item:selected do not work. The color do not change when I select a item.
What's the wrong with my code?
The problem is that you're setting a QWidget for the item, and since you're using a universal selector (with the wildcard), the result is that all QWidget will have that background color, including those added as item widgets for the list view.
The color you used for the :selected pseudo is only valid for the item painted by the view, since the item widget has its own background set from the universal selector, that background won't be visible.
The solution is to use a proper selector combination ensuring that the rule only matches children of the list view that have a usable selector, and set a transparent color for those widgets.
A possibility is to set a custom property for the widgets that must be set before adding the widgets to the list (otherwise, you need to set the stylesheet after adding them, or request a style.unpolish()).
self.setStyleSheet('''
QWidget {
font-size: 15px;
background: rgb(150, 150, 150);
}
QListWidget::item:selected {
background: rgb(128,128,255);
}
QListWidget QWidget[widgetItem=true] {
background: transparent;
}
''')
# ...
w1 = QWidget()
w1.setProperty('widgetItem', True)
# ...
w2 = QWidget()
w2.setProperty('widgetItem', True)
# ...
Another way to do so is to use an "empty" subclass for widgets that are going to be added to the item view:
class CustomItemWidget(QWidget): pass
class Window(QWidget):
def __init__(self):
super().__init__()
self.setStyleSheet('''
QWidget {
font-size: 15px;
background: rgb(150, 150, 150);
}
QListWidget::item:selected {
background: rgb(128,128,255);
}
CustomItemWidget {
background: transparent;
}
''')
# ...
w1 = CustomItemWidget()
# ...
w2 = CustomItemWidget()
# ...
Consider that using universal selectors for colors is usually not a good idea, as it can result in inconsistent behavior, especially for complex widgets: for instance, the scroll bars of scroll areas (like QListWidget) might not be correctly styled and can even become unusable.
If you plan to have a common background color for all widgets, it's better to set the Window role of the application palette:
app = QApplication(sys.argv)
palette = app.palette()
palette.setColor(palette.Window, QColor(150, 150, 150))
app.setPalette(palette)
# ...
In this way the current style will know exactly when to use that color as background, or as a component for other UI elements.
So, i want to display both the text and the ICON as a menubar item.
I have used the below statement as:
self.helpMenu = menubar1.addMenu(QtGui.QIcon("home.png"),"&TEXT")
But this displays only the icon and not the text.
So need help to fix it
Premise
It seems that, despite Qt provides an addMenu() function to create a menu that has both an icon and text, it is not fully supported.
There is a related and very old bug report on the matter, which has been flagged as closed and "Out of scope". I cannot test it right now, but I'm going to suppose that it's due to the native menubar support, which is mostly intended for macOS and Linux distros that support that feature.
That said, a workaround is possible, and that's done through a QProxyStyle.
It's a bit complex, but it works seamlessly given that:
it's enabled only when the native menubar feature is not used (whether it's available or just disabled);
it uses the 'fusion' style or the default style on Windows;
The trick is to ensure that the proxy returns a correct size for sizeFromContents() that includes both the text and the icon if both exist, and to use the default implementations as much as possible in drawControl() and drawItemText() (which is called from more standard styles).
class MenuProxy(QtWidgets.QProxyStyle):
menuHack = False
alertShown = False
def useMenuHack(self, element, opt, widget):
if (element in (self.CT_MenuBarItem, self.CE_MenuBarItem) and
isinstance(widget, QtWidgets.QMenuBar) and
opt.icon and not opt.icon.isNull() and opt.text):
if not self.alertShown:
if widget.isNativeMenuBar():
# this will probably not be shown...
print('WARNING: menubar items with icons and text not supported for native menu bars')
styleName = self.baseStyle().objectName()
if not 'windows' in styleName and styleName != 'fusion':
print('WARNING: menubar items with icons and text not supported for "{}" style'.format(
styleName))
self.alertShown = True
return True
return False
def sizeFromContents(self, content, opt, size, widget=None):
if self.useMenuHack(content, opt, widget):
# return a valid size that includes both the icon and the text
alignment = (QtCore.Qt.AlignCenter | QtCore.Qt.TextShowMnemonic |
QtCore.Qt.TextDontClip | QtCore.Qt.TextSingleLine)
if not self.proxy().styleHint(self.SH_UnderlineShortcut, opt, widget):
alignment |= QtCore.Qt.TextHideMnemonic
width = (opt.fontMetrics.size(alignment, opt.text).width() +
self.pixelMetric(self.PM_SmallIconSize) +
self.pixelMetric(self.PM_LayoutLeftMargin) * 2)
textOpt = QtWidgets.QStyleOptionMenuItem(opt)
textOpt.icon = QtGui.QIcon()
height = super().sizeFromContents(content, textOpt, size, widget).height()
return QtCore.QSize(width, height)
return super().sizeFromContents(content, opt, size, widget)
def drawControl(self, ctl, opt, qp, widget=None):
if self.useMenuHack(ctl, opt, widget):
# create a new option with no icon to draw a menubar item; setting
# the menuHack allows us to ensure that the icon size is taken into
# account from the drawItemText function
textOpt = QtWidgets.QStyleOptionMenuItem(opt)
textOpt.icon = QtGui.QIcon()
self.menuHack = True
self.drawControl(ctl, textOpt, qp, widget)
self.menuHack = False
# compute the rectangle for the icon and call the default
# implementation to draw it
iconExtent = self.pixelMetric(self.PM_SmallIconSize)
margin = self.pixelMetric(self.PM_LayoutLeftMargin) / 2
top = opt.rect.y() + (opt.rect.height() - iconExtent) / 2
iconRect = QtCore.QRect(opt.rect.x() + margin, top, iconExtent, iconExtent)
pm = opt.icon.pixmap(widget.window().windowHandle(),
QtCore.QSize(iconExtent, iconExtent),
QtGui.QIcon.Normal if opt.state & self.State_Enabled else QtGui.QIcon.Disabled)
self.drawItemPixmap(qp, iconRect, QtCore.Qt.AlignCenter, pm)
return
super().drawControl(ctl, opt, qp, widget)
def drawItemText(self, qp, rect, alignment, palette, enabled, text, role=QtGui.QPalette.NoRole):
if self.menuHack:
margin = (self.pixelMetric(self.PM_SmallIconSize) +
self.pixelMetric(self.PM_LayoutLeftMargin))
rect = rect.adjusted(margin, 0, 0, 0)
super().drawItemText(qp, rect, alignment, palette, enabled, text, role)
class Test(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
menu = self.menuBar().addMenu(QtGui.QIcon.fromTheme('document-new'), 'File')
menu.addAction(QtGui.QIcon.fromTheme('application-exit'), 'Quit')
self.menuBar().addMenu(QtGui.QIcon.fromTheme('edit-cut'), 'Edit')
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle(MenuProxy(QtWidgets.QStyleFactory.create('fusion')))
# or, for windows systems:
# app.setStyle(MenuProxy())
test = Test()
test.show()
sys.exit(app.exec_())
I have the same story with Windows 7 and PyQt 5.12.2 and tried to solve it like this:
import sys
from PyQt5.Qt import *
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.centralWidget = QLabel("Hello, World")
self.centralWidget.setAlignment(Qt.AlignCenter)
self.setCentralWidget(self.centralWidget)
menuBar = QMenuBar(self)
self.setMenuBar(menuBar)
self.helpContentAction = QAction(QIcon("img/readMe.png"), "&Help Content", self)
self.aboutAction = QAction("&About", self)
# helpMenu = menuBar.addMenu(QIcon("img/qtlogo.png"), "&Help")
helpMenu = menuBar.addMenu(" &Help") # +++
# ^^^^^^^^^^^^
helpMenu.addAction(self.helpContentAction)
helpMenu.addAction(self.aboutAction)
qss = """
QMenuBar {
background-color: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 lightgray, stop:1 darkgray
);
}
QMenuBar::item {
background-color: darkgray;
padding: 1px 5px 1px -25px; /* +++ */
background: transparent;
image: url(img/qtlogo.png); /* +++ * /
}
QMenuBar::item:selected {
background-color: lightgray;
}
QMenuBar::item:pressed {
background: lightgray;
}
"""
if __name__ == "__main__":
app = QApplication(sys.argv)
# app.setStyle('Fusion')
app.setStyleSheet(qss) # +++
app.setFont(QFont("Times", 10, QFont.Bold))
win = Window()
win.setWindowTitle("Python Menus")
win.resize(600, 350)
win.show()
sys.exit(app.exec_())
How to create a Stylesheet for Mulitiple QLabels or Multiple Qwidgets in PyQt5 ?
For example, In my programme, I use 8 QLabels, Out of Which 4 QLabels belong to one family/group and another 4 have a another family/group. Now I want to create a separate style sheet for both families. First family (all 4 QLabels) have to set the same property ( Background color, foreground color, Alignment, and font) and the second family also have to set different properties.
import sys
from PyQt5.QtWidgets import QWidget,QApplication,QLabel,QFormLayout
class Stylesheet_001(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Style Sheet Example_001")
self.setMinimumSize(600,800)
self.setMaximumSize(600,800)
self.mydesign()
def mydesign(self):
lbl_normal = QLabel("Total Available Items :")
lbl_starts = QLabel("Item Starts With :")
lbl_contains = QLabel("Items Contains Anywhere :")
lbl_end = QLabel("Items Ends With :")
lbl_normal_count = QLabel("500")
lbl_starts_count = QLabel('50,000')
lbl_contains_count = QLabel('5')
lbl_ends_count = QLabel('0')
mylayout = QFormLayout()
mylayout.addRow(lbl_normal ,lbl_normal_count)
mylayout.addRow(lbl_starts ,lbl_starts_count)
mylayout.addRow(lbl_contains,lbl_contains_count)
mylayout.addRow(lbl_end ,lbl_ends_count)
self.setLayout(mylayout)
def main():
myapp = QApplication(sys.argv)
mywindow = Stylesheet_001()
mywindow.show()
sys.exit(myapp.exec_())
if __name__ == "__main__":
main()
1) lbl_normal, 2) lbl_strats, 3) lbl_contains , 4) lbl_ends belong to one group (First) and another 4 Labels belong to another group (second group).
First group have to set same, fore-ground color:Red,font : Caliber,10,Bold and Alignment to Right.
Second group have to set same, fore-ground colour:Green,font:system default and Alignment to Left.
Try it:
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QLabel, QFormLayout,\
QFrame, QVBoxLayout
from PyQt5.QtCore import Qt
class Stylesheet_001(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Style Sheet Example_001")
self.setMinimumSize(600,800)
self.setMaximumSize(600,800)
self.mydesign()
def mydesign(self):
# Red, same font : Caliber, 10, Bold, and Alignment to Right
lbl_normal = QLabel("Total Available Items :", alignment=Qt.AlignRight | Qt.AlignVCenter)
lbl_normal.setMinimumWidth(180)
lbl_starts = QLabel("Item Starts With :", minimumWidth=180, alignment=Qt.AlignRight | Qt.AlignVCenter)
lbl_contains = QLabel("Items Contains Anywhere :", minimumWidth=180, alignment=Qt.AlignRight | Qt.AlignVCenter)
lbl_end = QLabel("Items Ends With :", minimumWidth=180, alignment=Qt.AlignRight | Qt.AlignVCenter)
lbl_normal_count = QLabel("500")
lbl_starts_count = QLabel('50,000')
lbl_contains_count = QLabel('5')
lbl_ends_count = QLabel('0')
mylayout = QFormLayout(self)
mylayout.addRow(lbl_normal , lbl_normal_count)
mylayout.addRow(lbl_starts , lbl_starts_count)
mylayout.addRow(lbl_contains, lbl_contains_count)
mylayout.addRow(lbl_end , lbl_ends_count)
QSS = """
QWidget > QLabel[text="Total Available Items :"],
QWidget > QLabel[text="Item Starts With :"],
QWidget > QLabel[text="Items Contains Anywhere :"],
QWidget > QLabel[text="Items Ends With :"] {
background-color: red;
color: white;
font: bold 10pt \"Caliber\";
}
QWidget > QLabel {
background-color: green;
color: yellow;
font: 10pt \"Caliber\";
}
"""
def main():
myapp = QApplication(sys.argv)
myapp.setStyle('Fusion')
myapp.setStyleSheet(QSS)
mywindow = Stylesheet_001()
mywindow.show()
sys.exit(myapp.exec_())
if __name__ == "__main__":
main()
Try it :
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Stylesheet_001(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Style Sheet Example_001")
self.setMinimumSize(600,800)
# self.setMaximumSize(600,800)
self.mydesign()
def mydesign(self):
lbl_normal = QLabel("Total Available Items :")
lbl_starts = QLabel("Item Starts With :")
lbl_contains = QLabel("Items Contains Anywhere :")
lbl_end = QLabel("Items Ends With :")
lbl_normal.setStyleSheet(self.stylesheet_family_1())
lbl_starts.setStyleSheet(self.stylesheet_family_1())
lbl_contains.setStyleSheet(self.stylesheet_family_1())
lbl_end.setStyleSheet(self.stylesheet_family_1())
lbl_normal_count = QLabel("500")
lbl_starts_count = QLabel('50,000')
lbl_contains_count = QLabel('5')
lbl_ends_count = QLabel('0')
lbl_normal_count.setStyleSheet(self.stylesheet_family_2())
lbl_starts_count.setStyleSheet(self.stylesheet_family_2())
lbl_contains_count.setStyleSheet(self.stylesheet_family_2())
lbl_ends_count.setStyleSheet(self.stylesheet_family_2())
self.mylayout = QFormLayout()
self.mylayout.setSpacing(0)
self.mylayout.addRow(lbl_normal ,lbl_normal_count)
self.mylayout.addRow(lbl_starts ,lbl_starts_count)
self.mylayout.addRow(lbl_contains,lbl_contains_count)
self.mylayout.addRow(lbl_end ,lbl_ends_count)
self.myframe = QFrame()
self.mainlayout = QVBoxLayout()
self.myframe.setFixedSize(400,300)
self.myframe.setLayout(self.mylayout)
self.mainlayout.addWidget(self.myframe)
self.mainlayout.addStretch()
self.setLayout(self.mainlayout)
def stylesheet_family_1(self):
return"""
QLabel{
background-color:'red';
font-family: Caliber;
font-style: normal;
font-size:10pt;
font-weight:normal;
border-width:1px;
border-color:black;
border-top-color:black;
border-style:outset;
color:white;
padding:6px;
min-width:220px;
qproperty-alignment:'AlignRight';
}
"""
def stylesheet_family_2(self):
return"""
QLabel{
background-color:'green';
font-family: Caliber;
font-style: normal;
font-size:10pt;
font-weight:bold;
border-width:1px;
border-color:black;
border-top-color:black;
border-style:outset;
color:white;
padding:1px;
min-width:20px;
qproperty-alignment:'AlignCenter|AlignRight';
}
"""
def main():
myapp = QApplication(sys.argv)
mywindow = Stylesheet_001()
mywindow.show()
sys.exit(myapp.exec_())
if __name__ == "__main__":
main()
I have to create a custom widget that looks like the following:
custom_widget_sketch
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)
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)
The final screen would look like this:
main_window_sketch
Considering all of these requirements I have the following questions:
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 of QVBoxLayout and QHBoxLayout to arrange the QLineEdits, 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 a QLineEdit?
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
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 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_()
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:
There's no need to use QPainter for the blue square, as you can use stylesheets for your whole widget, the trick is to use selectors.
I tried to create your widget and used this stylesheet:
Battery {
background-color: white;
}
QFrame#statusFrame {
background-color: rgb(64, 112, 190);
}
QFrame#statusFrame QLabel {
color: white;
font-weight: bold;
font-size: 24pt;
}
QLineEdit {
border: 1px solid black;
font-size: 24pt;
}
#serialLabel {
font-weight: bold;
font-size: 16pt;
}
I created a "container" QWidget, the status rectangle is actually a QFrame with its own layout, which I named statusFrame (you can set it in designer, or by means of setObjectName(str)).
By using object names and child selectors, I was able to set specific fonts for its labels by using the QFrame#statusFrame QLabel selector (which means "apply to each QLabel that is a child of a QFrame"); I also set the serialLabel object name to the s/n label, allowing me to set a different font size.
You can do this from code or using designer, just remember to set the right object names and parent/children hierarchy.
I was able to draw the "connector" part too, which requires to set fixed margins to the main widget:
class Battery(QtWidgets.QWidget):
connPath = QtGui.QPainterPath()
connPath.addRect(30, 10, 40, 28)
connPath.moveTo(30, 16)
connPath.lineTo(45, 16)
connPath.moveTo(30, 24)
connPath.lineTo(45, 24)
connPath.moveTo(30, 32)
connPath.lineTo(45, 32)
cablePen = QtGui.QColor(77, 122, 194)
def __init__(self):
QtWidgets.QWidget.__init__(self)
# the following is only if you create the whole widget from code,
# otherwise ensure to set both widget and layout contentsMargins
# accordingly in designer
self.setContentsMargins(25, 50, 10, 10)
layout = QtWidgets.QGridLayout()
self.setLayout(layout)
layout.setContentsMargins(0, 0, 0, 0)
# ...
def paintEvent(self, event):
qp = QtGui.QPainter(self)
qp.setRenderHints(qp.Antialiasing)
qp.translate(.5, .5)
qp.drawPath(self.connPath)
qp.setPen(self.cablePen)
cablePath = QtGui.QPainterPath()
cablePath.moveTo(30, 24)
top = self.statusFrame.geometry().top()
cablePath.quadTo(0, top + 20, 25, top + 40)
qp.drawPath(cablePath)
As you can see, it's almost the same as yours.
I'm looking to change the colour of the Value text from default black to white.
I've got a stylesheet, but the color: white only seems to apply to the text, not the value text.
'''
Load UI
'''
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
app.setStyleSheet("""
QMainWindow {background-color: rgb(80,80,80); color: white;}
QProgressDialog {background-color: rgb(80,80,80); color: white;}
""")
sys.exit(app.exec_())
I've also tried adding the QProgressBar to the stylesheet, but this didn't do anything either.
This is my code for the progress dialog:
def pathCasingFixFUNC(self):
'''
Fixes the path files that were named badly in notepad ++
'''
self.XprobBadCasing = ["List of bad file paths i'm checking"]
Xprogress = QtGui.QProgressDialog("Converting Path Names...", "Cancel", 0, len(self.XprobBadCasing), self)
Xprogress.setWindowModality(QtCore.Qt.WindowModal)
Xprogress.setWindowTitle('Processing')
Can i set the value font colour using Xprogress.value.setFont() or something?