How to add checkable ability to buttons when clicking on one of them had the checked mode and the other buttons are unchecked.
That is, one button can be checked at a time.
from PyQt5.QtWidgets import *
import sys
class Window(QWidget):
def __init__(self):
QWidget.__init__(self)
layout = QGridLayout()
self.setLayout(layout)
btn1 = QPushButton()
btn1.setChecked(True)
btn1.setStyleSheet("background-color: rgba(255, 0, 0, 0.61);")
layout.addWidget(btn1, 0, 0)
btn2 = QPushButton()
btn2.setStyleSheet("background-color: rgb(0, 255, 34);")
layout.addWidget(btn2, 0, 1)
btn3 = QPushButton()
btn3.setStyleSheet("background-color: rgb(49, 49, 49);")
layout.addWidget(btn3, 0, 2)
app = QApplication(sys.argv)
screen = Window()
screen.show()
sys.exit(app.exec_())
Related
I wish to have a QGridLayout containing some informations that can be dynamicaaly changed. However, as it is, it will only superimpose the different informations on top of the previous one instead of replacing it. Surprisingly I couldn't find a method to remove or clean or such a widget from a grid. So what, can't it be dynamically changed ?...
Here is an example of code :
import sys
from PyQt5.QtWidgets import (
QApplication,
QGridLayout,
QPushButton,
QWidget,
QLabel
)
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QGridLayout Example")
# Create a QGridLayout instance
self.buttonA = QPushButton("A")
self.buttonB = QPushButton("B")
self.layout = QGridLayout()
# Add widgets to the layout
self.layout.addWidget(self.buttonA, 0, 1)
self.layout.addWidget(self.buttonB, 0, 2)
self.layout.addWidget(QPushButton("C"), 1, 0)
self.layout.addWidget(QPushButton("D"), 1, 1)
self.layout.addWidget(QPushButton("E"), 1, 2)
self.layout.addWidget(QPushButton("F"), 2, 0)
self.layout.addWidget(QPushButton("G"), 2, 1)
self.layout.addWidget(QPushButton("H"), 2, 2)
# Set the layout on the application's window
self.setLayout(self.layout)
self.buttonA.clicked.connect(self.change_label)
self.buttonB.clicked.connect(self.change_label2)
def change_label(self):
self.label = QLabel("Hello")
self.layout.addWidget(self.label, 0, 0)
def change_label2(self):
self.label = QLabel("Bonjour")
self.layout.addWidget(self.label, 0, 0)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
When one clicks on button A, I want to have displayed in box (0,0) "Hello". Then if one clicks on button B, I want to replace the text "Hello" with "Bonjour". However I can only have one text on top of the other which is obviously hardly readable then.
Can someone help me ?
Just use this code:
import sys
from PyQt5.QtWidgets import (
QApplication,
QGridLayout,
QPushButton,
QWidget,
QLabel
)
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QGridLayout Example")
# Create a QGridLayout instance
self.label = QLabel("Show text here")
self.buttonA = QPushButton("A")
self.buttonB = QPushButton("B")
self.layout = QGridLayout()
# Add widgets to the layout
self.layout.addWidget(self.label, 0, 0)
self.layout.addWidget(self.buttonA, 0, 1)
self.layout.addWidget(self.buttonB, 0, 2)
self.layout.addWidget(QPushButton("C"), 1, 0)
self.layout.addWidget(QPushButton("D"), 1, 1)
self.layout.addWidget(QPushButton("E"), 1, 2)
self.layout.addWidget(QPushButton("F"), 2, 0)
self.layout.addWidget(QPushButton("G"), 2, 1)
self.layout.addWidget(QPushButton("H"), 2, 2)
# Set the layout on the application's window
self.setLayout(self.layout)
self.buttonA.clicked.connect(self.change_label)
self.buttonB.clicked.connect(self.change_label2)
def change_label(self):
self.label.setText("Hello")
def change_label2(self):
self.label.setText("Bonjour")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
The window would have two layouts: A, the main layout to show some images; B, the qlabel to show some status. When the window is started, A would be empty. A would show some images after some operations.
My question is: how to let B show in the bottom? The current code is:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class TimeLine(QMainWindow):
def __init__(self):
super(TimeLine, self).__init__()
widget = QWidget()
self.setCentralWidget(widget)
layout = QVBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
widget.setLayout(layout)
statusLabel = QLabel('status bar')
statusLabel.setStyleSheet("background-color:blue")
statusLabel.setMaximumHeight(20)
layout.addWidget(statusLabel)
layout.setSpacing(0)
app = QApplication(sys.argv)
window = TimeLine()
window.show()
app.exec_()
And the result is:
The blue label shows in the middle, and I want it to be show in the bottom.
Then, I add a stretch. The layout B would show in the bottom, however, the layout A would also be squeezed. The code is:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class TimeLine(QMainWindow):
def __init__(self):
super(TimeLine, self).__init__()
widget = QWidget()
self.setCentralWidget(widget)
layout = QVBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
widget.setLayout(layout)
mainLabel = QLabel()
mainLabel.setStyleSheet("background-color:yellow")
statusLabel = QLabel()
statusLabel.setStyleSheet("background-color:blue")
statusLabel.setMaximumHeight(20)
layout.addWidget(mainLabel)
layout.addStretch()
layout.addWidget(statusLabel)
layout.setSpacing(0)
app = QApplication(sys.argv)
window = TimeLine()
window.show()
app.exec_()
And the result is:
The yellow label is the main label, the gray color represents the back ground. I want the yellow label to occupy all the window except from the blue label.
Thus, what I want is:
when there is no other label, I hope the blue label show in the bottom, like:
where there is another label (yellow label), I hope the yellow label occupy all the space except from the blue label, like:
I saw your task like this:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class TimeLine(QMainWindow):
def __init__(self):
super(TimeLine, self).__init__()
widget = QWidget()
self.setCentralWidget(widget)
mainLabel = QLabel("This is a label.", alignment = Qt.AlignCenter)
mainLabel.setStyleSheet("background-color:yellow")
layout = QVBoxLayout(widget)
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(mainLabel)
self.statusBar().setStyleSheet("background-color:blue; color: #fff")
self.statusBar().showMessage('Hello {} !'.format('status bar'))
if __name__ == "__main__":
app = QApplication(sys.argv)
window = TimeLine()
window.show()
sys.exit(app.exec_())
If I understand your question correctly, you want the blue label to be aligned with the bottom edge of the main window at all times. One way to get what you want to to set the alignment of the label to Qt.AlignBottom when adding it to the layout. You also need to adjust the stretch factors of the two labels to make sure the yellow label takes up all the space above the blue label when it's present, i.e.
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
class TimeLine(QMainWindow):
def __init__(self):
super(TimeLine, self).__init__()
widget = QWidget()
self.setCentralWidget(widget)
layout = QVBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
widget.setLayout(layout)
mainLabel = QLabel()
mainLabel.setStyleSheet("background-color:yellow")
statusLabel = QLabel('status bar')
statusLabel.setStyleSheet("background-color:blue")
statusLabel.setMaximumHeight(20)
layout.addWidget(mainLabel, stretch = 1)
layout.addWidget(statusLabel, stretch = 0, alignment = Qt.AlignBottom)
layout.setSpacing(0)
app = QApplication(sys.argv)
window = TimeLine()
window.show()
app.exec_()
Both labels:
Blue label only:
I put three label in a window, however, the three labels only occupy small part of the window. Here is my code:
from PyQt5.QtWidgets import *
import sys
class ThreeDMPRWindow(QMainWindow):
def __init__(self, image=None):
super(ThreeDMPRWindow, self).__init__()
self.resize(800, 600)
widget = QWidget()
self.setCentralWidget(widget)
layout = QVBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
widget.setLayout(layout)
allLayout = QHBoxLayout()
layout1 = QVBoxLayout()
label1 = QLabel('label 1')
label1.setStyleSheet("background: rgb(255,0,0)")
layout1.addWidget(label1)
layout2 = QVBoxLayout()
label2 = QLabel('label 2')
label2.setStyleSheet("background: rgb(255,0,0)")
layout2.addWidget(label2)
layout3 = QVBoxLayout()
label3 = QLabel('label 3')
label3.setStyleSheet("background: rgb(255,0,0)")
layout3.addWidget(label3)
qlayout = QGridLayout()
qlayout.addLayout(layout1, 0, 0, 2, 1)
qlayout.addLayout(layout2, 0, 1, 1, 1)
qlayout.addLayout(layout3, 1, 1, 1, 1)
allLayout.addLayout(qlayout)
allLayout.addLayout(QVBoxLayout())
layout.addLayout(allLayout)
app = QApplication(sys.argv)
window = ThreeDMPRWindow()
window.show()
app.exec_()
If we annotate the code: allLayout.addLayout(QVBoxLayout()), the three labels would occupy the whole window. I don't know why this code makes such difference. But I can't remove the code allLayout.addLayout(QVBoxLayout()), because I need the new layout for some other widgets.
If you want to have a space where you can add other widgets then you must use QWidget instead of QVBoxLayout, and in that QWidget add the QVBoxLayout:
# ...
allLayout.addLayout(qlayout)
empty_widget = QWidget()
empty_widget.setContentsMargins(0, 0, 0, 0)
lay = QVBoxLayout(empty_widget)
allLayout.addWidget(empty_widget)
layout.addLayout(allLayout)
# ...
Output:
I have this code:
#!/usr/bin/env python3
from PyQt5.QtWidgets import *
import sys
class Window(QWidget):
def __init__(self):
QWidget.__init__(self)
layout = QGridLayout()
self.setLayout(layout)
label_1 = QLabel("label 1")
layout.addWidget(label_1, 0, 0)
label_2 = QLabel("label 2")
layout.addWidget(label_2, 0, 1)
label_3 = QLabel("label 3")
layout.addWidget(label_3, 1, 0)
app = QApplication(sys.argv)
screen = Window()
screen.show()
sys.exit(app.exec_())
I have this result:
but I need this:
How can I do it?
The fourth and fifth arguments of addWidget allow you to specify how many rows and columns to span:
label_3 = QLabel("label 3")
layout.addWidget(label_3, 1, 0, 1, 2)
This is the example code for layout the QLabel. It is PyQt4, but you can try with PyQt5 with small changes.
import sys
from PyQt4 import QtGui
class Window (QtGui.QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.verticalLayout = QtGui.QVBoxLayout (self)
self.verticalLayout.setObjectName ('verticalLayout')
self.gridLayout = QtGui.QGridLayout()
self.gridLayout.setObjectName ('gridLayout')
self.label_1 = QtGui.QLabel(self)
self.label_1.setObjectName('label_1')
self.label_1.setText ('Label_1')
self.label_1.setStyleSheet('background-color: rgb(182, 182, 182);')
self.label_2 = QtGui.QLabel(self)
self.label_2.setObjectName('label_2')
self.label_2.setText ('Label_2')
self.label_2.setStyleSheet('background-color: rgb(182, 182, 182);')
self.label_3 = QtGui.QLabel(self)
self.label_3.setObjectName('label_3')
self.label_3.setText ('Label_3')
self.label_3.setStyleSheet('background-color: rgb(182, 182, 182);')
self.gridLayout.addWidget(self.label_1, 0, 0, 1, 1)
self.gridLayout.addWidget(self.label_2, 0, 1, 1, 1)
self.gridLayout.addWidget(self.label_3, 1, 0, 1, 2)
self.verticalLayout.addLayout(self.gridLayout)
self.resize(300, 100)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
With four QAction buttons added to QToolBar what widgets properties need to be set and to what value to make no spacing between the buttons. So each button is placed side by side?
As it can be seen from the example posted below I've tried to achieve zero spacing with:
toolbar.setContentsMargins(0, 0, 0, 0)
toolbar.layout().setSpacing(0)
toolbar.layout().setContentsMargins(0, 0, 0, 0)
but it makes no difference and the buttons are still spaced from each other....
import sys
from PyQt4.QtGui import *
class Window(QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.initUI()
def initUI(self):
textEdit = QTextEdit()
self.setCentralWidget(textEdit)
btn1 = QAction(QIcon('icons/btn1.png'), 'Button 01', self)
btn2 = QAction(QIcon('icons/btn2.png'), 'Button 02', self)
btn3 = QAction(QIcon('icons/btn3.png'), 'Button 03', self)
btn3.setEnabled(False)
btn1.setShortcut('Ctrl+Q')
btn1.triggered.connect(self.close)
toolbar = self.addToolBar('Exit')
toolbar.addAction(btn1)
toolbar.addAction(btn2)
toolbar.addAction(btn3)
toolbar.addSeparator()
toolbar.setContentsMargins(0, 0, 0, 0)
toolbar.layout().setSpacing(0)
toolbar.layout().setContentsMargins(0, 0, 0, 0)
self.setGeometry(300, 300, 350, 250)
self.setWindowTitle('Main window')
self.show()
def main():
app = QApplication(sys.argv)
ex = Window()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
From the stylesheet examples for QToolBar:
spacing: 3px; /* spacing between items in the tool bar */
So this should do the trick:
toolbar.setStyleSheet("QToolBar{spacing:0px;}");