The code below creates a dialog window with a QSplitter.
The left and right side of splitter is assigned a dark-colored QWidget.
Each QWidget layout's spacing was set to 0 (zero) (so there should be no margin).
To each of these 0-spacing layouts there was a light colored QLabel added.
I want QLabel to fill an entire QWidget with no spacing or margin. So QLabel would expand and to extend from edge to edge. Ideally we would not see the dark color of the QWidget. How could we modify the code so the QLabel extends from edge to edge inside of QWidget?
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
app = QApplication([])
window = QDialog()
window.setLayout(QVBoxLayout())
window.resize(400, 250)
splitter = QSplitter(Qt.Horizontal)
window.layout().addWidget(splitter)
for side in ['left', 'right']:
widget = QWidget()
widget.setStyleSheet("background-color:gray;")
widget_layout = QVBoxLayout()
widget_layout.setSpacing(0)
widget.setLayout(widget_layout)
label = QLabel('%s side QLabel' % side.capitalize())
label.setAlignment(Qt.AlignCenter)
label.setStyleSheet("background-color:lightgray;")
widget.layout().addWidget(label)
splitter.addWidget(widget)
window.show()
sys.exit(app.exec_())
You must set the layout margins to 0:
widget_layout.setContentsMargins(0, 0, 0, 0)
Code:
app = QApplication(sys.argv)
window = QDialog()
window.setLayout(QVBoxLayout())
window.resize(400, 250)
splitter = QSplitter(Qt.Horizontal)
window.layout().addWidget(splitter)
for side in ['left', 'right']:
widget = QWidget()
widget.setStyleSheet("background-color:gray;")
widget_layout = QVBoxLayout()
widget_layout.setContentsMargins(0, 0, 0, 0) # this line
widget_layout.setSpacing(0)
widget.setLayout(widget_layout)
label = QLabel('%s side QLabel' % side.capitalize())
label.setAlignment(Qt.AlignCenter)
label.setStyleSheet("background-color:lightgray;")
label.setContentsMargins(0, 0, 0, 0)
widget.layout().addWidget(label)
splitter.addWidget(widget)
window.show()
sys.exit(app.exec_())
Screenshot:
Note: setSpacing() is unnecessary in this case since this indicates the space between widgets inside a layout, but in this case only the QLabel is only in the layout.
You can also use:
splitter->setHandleWidth(1);
Related
I'm designing graphic editor. As a scene for drawing, I need to use exactly QGraphicsScene. I implemented adding rectangles and ellipses to the scene with two buttons.
I need to implement dragging the faigures from the panel to the canvas, approximately as in the picture:Shape Selection Panel
What widgets or buttons can I use for this custom panel? Maybe there is an information an example with the implementation of a similar panel?
The program code with the implementation of adding shapes and the interface image:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
# window class
class Window(QMainWindow):
def __init__(self):
super().__init__()
wid = QWidget()
self.setCentralWidget(wid)
# setting title
self.setWindowTitle("Paint with PyQt5")
# setting geometry to main window
self.setGeometry(100, 100, 800, 600)
# Defining a scene rect of 400x200, with it's origin at 0,0.
# If we don't set this on creation, we can set it later with .setSceneRect
self.scene = QGraphicsScene(0, 0, 400, 200)
# Set all items as moveable and selectable.
for item in self.scene.items():
item.setFlag(QGraphicsItem.ItemIsMovable)
item.setFlag(QGraphicsItem.ItemIsSelectable)
# Define our layout.
vbox = QVBoxLayout()
up = QPushButton("Rect")
up.clicked.connect(self.add_rect)
vbox.addWidget(up)
down = QPushButton("Elips")
down.clicked.connect(self.add_elips)
vbox.addWidget(down)
view = QGraphicsView(self.scene)
view.setRenderHint(QPainter.Antialiasing)
hbox = QHBoxLayout(self)
hbox.addLayout(vbox)
hbox.addWidget(view)
wid.setLayout(hbox)
def add_rect(self):
rect = QGraphicsRectItem(0, 0, 200, 50)
rect.setPos(50, 20)
rect.setFlag(QGraphicsItem.ItemIsMovable)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
self.scene.addItem(rect)
def add_elips(self):
ellipse = QGraphicsEllipseItem(0, 0, 100, 100)
ellipse.setPos(75, 30)
ellipse.setFlag(QGraphicsItem.ItemIsMovable)
ellipse.setFlag(QGraphicsItem.ItemIsSelectable)
self.scene.addItem(ellipse)
# create pyqt5 app
App = QApplication(sys.argv)
# create the instance of our Window
window = Window()
# showing the window
window.show()
# start the app
sys.exit(App.exec())
Image of interface:
Image of interface
I have set up an image button with some text, but the image does not align with the text due to some extra margins. How can I get rid of these margins? I have tried setting setContentsMargins(0,0,0,0) and setSpacing(0) on various components but it doesn't seem to affect the correct margins.
Here is a demo:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class ImageButton(QWidget):
def __init__(self, img_location):
QWidget.__init__(self)
self.img_location = img_location
self.button = QToolButton(self)
self.button.clicked.connect(self.handleButton)
self.button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
self.button.setIcon(QIcon(img_location))
self.button.setIconSize(QSize(300,400))
layout = QVBoxLayout(self)
layout.addWidget(self.button)
def handleButton(self):
print(self.img_location)
app = QApplication([])
window = QMainWindow()
window.resize(800,600)
label_title = QLabel("bob asdfjak f ajksf asljf ajdslf aldskj ksf kslfhadjks lfhiu sofhjaklfsiuod fahklfhadisufaksufhdsuifhosa fasdf afsda")
label_title.setStyleSheet('background-color: yellow')
label_title.setAlignment(Qt.AlignCenter)
label_title.adjustSize()
label_title.setWordWrap(True)
imgbtn = ImageButton("a.png")
imgbtn.setStyleSheet('background-color: green')
layout_box = QVBoxLayout()
layout_box.setContentsMargins(0,0,0,0)
layout_box.setSpacing(0)
layout_box.addWidget(imgbtn, 0, Qt.AlignTop)
layout_box.addWidget(label_title, 0, Qt.AlignTop)
layout_box.setAlignment(Qt.AlignCenter)
layout_box.setSpacing(0)
content = QWidget()
content.setStyleSheet('background-color: blue')
content.setFixedWidth(300)
content.setFixedHeight(400)
content.setLayout(layout_box)
window.setCentralWidget(content)
window.show()
app.exec_()
The Yellow region marks the text label, the Green region marks the imagebutton, and the Blue region marks the space I'm trying to get rid of. See how the yellow region expands to the size of the blue, with the end result that the text doesn't align to the imagebutton.
How can I get rid of this blue region?
That margin is that of the QVBoxLayout that you use to place the QToolButton inside ImageButton, so the solution is to set it to 0 that margin:
# ...
class ImageButton(QWidget):
def __init__(self, img_location):
super().__init__(self)
# ...
layout = QVBoxLayout(self)
layout.addWidget(self.button)
layout.setContentsMargins(0, 0, 0, 0)
# ...
I have set up an image button with some text, but the image does not align with the text due to some extra margins. How can I get rid of these margins? I have tried setting setContentsMargins(0,0,0,0) and setSpacing(0) on various components but it doesn't seem to affect the correct margins.
Here is a demo:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class ImageButton(QWidget):
def __init__(self, img_location):
QWidget.__init__(self)
self.img_location = img_location
self.button = QToolButton(self)
self.button.clicked.connect(self.handleButton)
self.button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
self.button.setIcon(QIcon(img_location))
self.button.setIconSize(QSize(300,400))
layout = QVBoxLayout(self)
layout.addWidget(self.button)
def handleButton(self):
print(self.img_location)
app = QApplication([])
window = QMainWindow()
window.resize(800,600)
label_title = QLabel("bob asdfjak f ajksf asljf ajdslf aldskj ksf kslfhadjks lfhiu sofhjaklfsiuod fahklfhadisufaksufhdsuifhosa fasdf afsda")
label_title.setStyleSheet('background-color: yellow')
label_title.setAlignment(Qt.AlignCenter)
label_title.adjustSize()
label_title.setWordWrap(True)
imgbtn = ImageButton("a.png")
imgbtn.setStyleSheet('background-color: green')
layout_box = QVBoxLayout()
layout_box.setContentsMargins(0,0,0,0)
layout_box.setSpacing(0)
layout_box.addWidget(imgbtn, 0, Qt.AlignTop)
layout_box.addWidget(label_title, 0, Qt.AlignTop)
layout_box.setAlignment(Qt.AlignCenter)
layout_box.setSpacing(0)
content = QWidget()
content.setStyleSheet('background-color: blue')
content.setFixedWidth(300)
content.setFixedHeight(400)
content.setLayout(layout_box)
window.setCentralWidget(content)
window.show()
app.exec_()
The Yellow region marks the text label, the Green region marks the imagebutton, and the Blue region marks the space I'm trying to get rid of. See how the yellow region expands to the size of the blue, with the end result that the text doesn't align to the imagebutton.
How can I get rid of this blue region?
That margin is that of the QVBoxLayout that you use to place the QToolButton inside ImageButton, so the solution is to set it to 0 that margin:
# ...
class ImageButton(QWidget):
def __init__(self, img_location):
super().__init__(self)
# ...
layout = QVBoxLayout(self)
layout.addWidget(self.button)
layout.setContentsMargins(0, 0, 0, 0)
# ...
I have a toplevel widget with a layout set and 2 other widgets added to that layout, when I color them all I only see the toplevel widget color but Id like to see the children widgets on top. This is what I have attempted but it just displays a blue QWidget, I am expecting red and green widgets one on top of the other
def set_color(widget, color):
p = widget.palette()
p.setColor(widget.backgroundRole(), color)
widget.setPalette(p)
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget,QVBoxLayout
app = QApplication([])
win = QWidget()
win.show()
win.resize(1920,1080)
vlayout = QVBoxLayout()
win.setLayout(vlayout)
set_color(win, Qt.blue)
mod_group = QWidget()
mod_layout = QHBoxLayout()
mod_group.setLayout(mod_layout)
vlayout.addWidget(mod_group)
set_color(mod_group, Qt.red)
mod_group.show()
audio_group = QWidget()
audio_layout = QHBoxLayout()
vlayout.addWidget(audio_group)
audio_group.setLayout(audio_layout)
set_color(audio_group, Qt.green)
audio_group.show()
The widgets are visible but the background color you use is the same as the parent widget, so that they are applied correctly you must enable the autoFillBackground property:
mod_group.setAutoFillBackground(True)
audio_group.setAutoFillBackground(True)
I'm trying to put a QProgressBar below a QPushButton and align them on the center of a QVBoxLayout, but for some reason the button stays left aligned when the progress bar is present and center aligned if it is not.
I tried setting the alignment of all parent widgets and layouts to Qt.AlignCenter, but the progress bar keeps making the button go to the left.
connect_box = QVBoxLayout()
connect_box.setAlignment(Qt.AlignCenter)
connect_button = QPushButton('Connect')
connect_button.setFixedSize(120, 30)
connect_progress = QProgressBar()
connect_progress.setRange(0, 10000)
connect_progress.setValue(0)
connect_box.addWidget(connect_button)
connect_box.addWidget(connect_progress)
connect_box.setContentsMargins(0, 20, 0, 0)
I expect the button to stay center aligned when the progress bar is added.
Try it:
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class MyWidget(QWidget):
def __init__(self):
super().__init__()
connect_button = QPushButton('Connect')
connect_button.setFixedSize(120, 30)
connect_progress = QProgressBar()
connect_progress.setRange(0, 10000)
connect_progress.setValue(0)
connect_box = QVBoxLayout(self)
connect_box.setAlignment(Qt.AlignCenter)
connect_box.addWidget(connect_button, alignment=Qt.AlignCenter) # < ----
connect_box.addWidget(connect_progress)
connect_box.setContentsMargins(0, 20, 0, 0)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.show()
sys.exit(app.exec_())