I am learning how to use PyQt5 and I came across this issue where "my first label" does not complete display on my screen.
Display after running the code:
Code:
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True) #enable highdpi scaling
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True) #use highdpi icons
def window():
app = QApplication(sys.argv)
win = QMainWindow()
win = QMainWindow()
win.setGeometry(200, 200, 400, 400)
win.setWindowTitle("Tech with Aeijan")
label = QtWidgets.QLabel(win)
label.setText("my first label!")
label.move(50,50)
win.show()
sys.exit(app.exec_())
window()
QLabel adapts its contents based on the (possible) parent layout manager, but you didn't use any, so it doesn't know how to correctly display itself or adapt its size to do that.
The simplest solution is to call label.adjustSize(), which will cause the label to resize itself so that it will be able to display its contents.
That wouldn't be a very good idea, though: you are trying to use a fixed position for a widget (which is normally considered a bad thing to do, for plenty of reasons); the result will be that if the label text is too big and the user resizes the window, the text won't be completely visible as it should be, nor the label would know how to resize or eventually wrap its contents to do ensure that all its text is shown.
The better approach is to use a layout manager, but that is a solution reserved for simpler widgets (like a QWidget or a QDialog); a QMainWindow doesn't work like that, and it requires a central widget to be set to ensure that its contents are correctly displayed and managed.
In your case, you could simply use self.setCentralWidget(label), but that would prevent you to add any other widget to your window.
A "container" widget should be used instead, and that widget would be set as the central one for the main window; then you can set a layout for that widget and add the label to it:
def window():
app = QApplication(sys.argv)
win = QMainWindow()
central = QWidget()
win.setCentralWidget(central)
layout = QVBoxLayout()
central.setLayout(layout)
# alternatively, the above is the same as this:
# layout = QVBoxLayout(central)
label = QtWidgets.QLabel(win)
label.setText("my first label!")
layout.addWidget(label)
# ...
Related
I am learning how to use PyQt5 and I came across this issue where "my first label" does not complete display on my screen.
Display after running the code:
Code:
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True) #enable highdpi scaling
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True) #use highdpi icons
def window():
app = QApplication(sys.argv)
win = QMainWindow()
win = QMainWindow()
win.setGeometry(200, 200, 400, 400)
win.setWindowTitle("Tech with Aeijan")
label = QtWidgets.QLabel(win)
label.setText("my first label!")
label.move(50,50)
win.show()
sys.exit(app.exec_())
window()
QLabel adapts its contents based on the (possible) parent layout manager, but you didn't use any, so it doesn't know how to correctly display itself or adapt its size to do that.
The simplest solution is to call label.adjustSize(), which will cause the label to resize itself so that it will be able to display its contents.
That wouldn't be a very good idea, though: you are trying to use a fixed position for a widget (which is normally considered a bad thing to do, for plenty of reasons); the result will be that if the label text is too big and the user resizes the window, the text won't be completely visible as it should be, nor the label would know how to resize or eventually wrap its contents to do ensure that all its text is shown.
The better approach is to use a layout manager, but that is a solution reserved for simpler widgets (like a QWidget or a QDialog); a QMainWindow doesn't work like that, and it requires a central widget to be set to ensure that its contents are correctly displayed and managed.
In your case, you could simply use self.setCentralWidget(label), but that would prevent you to add any other widget to your window.
A "container" widget should be used instead, and that widget would be set as the central one for the main window; then you can set a layout for that widget and add the label to it:
def window():
app = QApplication(sys.argv)
win = QMainWindow()
central = QWidget()
win.setCentralWidget(central)
layout = QVBoxLayout()
central.setLayout(layout)
# alternatively, the above is the same as this:
# layout = QVBoxLayout(central)
label = QtWidgets.QLabel(win)
label.setText("my first label!")
layout.addWidget(label)
# ...
This question already has an answer here:
PyQt5 label cut off
(1 answer)
Closed 2 years ago.
I have recently started learning pyQt5 and am running into an issue where the entire label does not show up on the window. Is there a quick fix for this? This is the code I have so far and the image of the window is attached as well -> Before button click:
After button click:
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
class MyWindow(QMainWindow):
# Create an innstance of QMainWindow
def __init__(self):
super(MyWindow, self).__init__() # parent constructor
self.setGeometry(400, 200, 1000, 750) # sets size of window
self.setWindowTitle("The birds work for the bourgeoisie") # sets title of window
self.initUI()
def initUI(self):
# stuff we want in window
# Step 1: Define an application
# Labels
self.label = QtWidgets.QLabel(self) # where label is located
self.label.setText("birb wants freedom")
self.label.move(400,200)
# Buttons
self.b1 = QtWidgets.QPushButton(self)
self.b1.setText("Free birb")
self.b1.move(410,230)
# Map button to an event
self.b1.clicked.connect(self.clicked)
# Step 2: Create event for button click
def clicked(self):
self.label.setText("FREEDOM AT LAST!")
def window():
app = QApplication(sys.argv) # passing cmmd line args to QtApp
win = MyWindow() # widget shown in the application
win.show() # brings up window
sys.exit(app.exec_()) # winndow shows up nicely and exits properly
window()
The label object has an adjust size method. From https://www.geeksforgeeks.org/pyqt5-how-to-auto-resize-label-adjustsize-qlabel/:
PyQt5 – How to auto resize Label | adjustSize QLabel
Last Updated : 26 Mar, 2020
During the designing of the GUI (Graphical User Interface) application there is a need to display plain text as information where label is used, but sometimes information text could be large or much smaller and it is difficult to use resize() method so have to auto adjust the size of the label according to the text, in order to do so adjustSize() method can be used.
adjustSize() method will change the size of label according to the length of the text, if the length is less it will decrease the length and height of the widget and vice versa.
Syntax : label.adjustSize()
Argument : It takes no argument.
I am trying to get the built in StandardPixmaps
to display on my layout.
So far I have managed to access a standard pixmap (PyQt4.QtGui.QStyle.SP_MessageBoxWarning), but seem unable to actually add this to my layout. I have tried adding it to a QLabel using the setPixmap method, but this requires a pixmap, not a standardPixmap.
I have found this answer on SO, which led me to the standardPixmaps, but I have been unable to make any more progress from here.
PyQt4.QtGui.QStyle.SP_MessageBoxWarning is an enumeration value not a pixmap.
In order to get a pixmap from it, you could give it to the standardPixmap method of the current used style.
Example:
from PyQt4 import QtGui
if __name__ == '__main__':
app = QtGui.QApplication([])
label = QtGui.QLabel()
label.setPixmap(app.style().standardPixmap(QtGui.QStyle.SP_MessageBoxWarning))
label.show()
app.exec_()
Unfortunately, the standardPixmap method is considered obsolete now. The Qt doc advises to use the standardIcon method which returns a QIcon.
If you still want to use a QLabel to display your icon, you have to build a QPixmap from the QIcon you get. You can use one of its pixmap methods for this:
from PyQt4 import QtGui
if __name__ == '__main__':
app = QtGui.QApplication([])
label = QtGui.QLabel()
icon = app.style().standardIcon(QtGui.QStyle.SP_MessageBoxWarning)
label.setPixmap(icon.pixmap(32))
label.show()
app.exec_()
Using PyQt4, when I hide a window and show it afterwards, it appears at another position (at least here on Linux). Example code:
#!/usr/bin/python3
from PyQt4.QtGui import *
app = QApplication([])
widget = QWidget()
widget.setLayout(QVBoxLayout())
label = QLabel()
widget.layout().addWidget(label)
def hideShow():
widget.hide()
widget.show()
widget.layout().addWidget(QPushButton('Hide/Show', clicked = hideShow))
widget.show()
app.exec_()
The window disappears and appears, but a bit below and to the right of the original position. I think it's displaced by the size of the window manager's frame around the actual widget.
How can I place the window at the exact position where it was? And why does it move at all? Shouldn't it stay where it is?
On Linux, window placement can be very unpredictable. See this section in the Qt documentation for a break-down of the issues.
There's probably no general solution to the problem, but for me, setting the geometry before the initial show() seems to work:
...
widget.setGeometry(200, 200, 100, 50)
widget.show()
app.exec_()
UPDATE
After some testing with the KDE window manager, I may have discovered a potential solution.
It seems that calling show() immediately after hide() does not give the window manager enough time to calculate the correct window position. So a simple workaround is to explicitly set the geometry after a small delay:
from PyQt4.QtGui import *
from PyQt4.QtCore import QTimer
app = QApplication([])
widget = QWidget()
widget.setLayout(QVBoxLayout())
label = QLabel()
widget.layout().addWidget(label)
def hideShow():
widget.hide()
QTimer.singleShot(25, showWidget)
def showWidget():
widget.setGeometry(widget.geometry())
widget.show()
widget.layout().addWidget(QPushButton('Hide/Show', clicked = hideShow))
widget.show()
app.exec_()
This works for me using KDE-4.8 and OpenBox, but of course YMMV.
I have had similar problem with xfce. Perhaps you could get the position before hiding it (or when displaying it, depending on what you want), store it away, and then set it when it is displayed again with setGeometry()? A bit hacky perhaps..
I'm having difficulty getting widgets in a QDialog resized automatically when the dialog itself is resized.
In the following program, the textarea resizes automatically if you resize the main window. However, the textarea within the dialog stays the same size when the dialog is resized.
Is there any way of making the textarea in the dialog resize automatically? I've tried using setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) on the dialog itself and the two widgets within, but that seems to have no effect.
I'm using Qt version 3.3.7 and PyQt version 3.5.5-29 on openSuSE 10.2, if that's relevant.
import sys
from qt import *
# The numbers 1 to 1000 as a string.
NUMBERS = ("%d " * 1000) % (tuple(range(1,1001)))
# Add a textarea containing the numbers 1 to 1000 to the given
# QWidget.
def addTextArea(parent, size):
textbox = QTextEdit(parent)
textbox.setReadOnly(True)
textbox.setMinimumSize(QSize(size, size*0.75))
textbox.setText(NUMBERS)
class TestDialog(QDialog):
def __init__(self,parent=None):
QDialog.__init__(self,parent)
self.setCaption("Dialog")
everything = QVBox(self)
addTextArea(everything, 400)
everything.resize(everything.sizeHint())
class TestMainWindow(QMainWindow):
def __init__(self,parent=None):
QMainWindow.__init__(self,parent)
self.setCaption("Main Window")
everything = QVBox(self)
addTextArea(everything, 800)
button = QPushButton("Open dialog", everything)
self.connect(button, SIGNAL('clicked()'), self.openDialog)
self.setCentralWidget(everything)
self.resize(self.sizeHint())
self.dialog = TestDialog(self)
def openDialog(self):
self.dialog.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainwin = TestMainWindow(None)
app.setMainWidget(mainwin)
mainwin.show()
app.exec_loop()
QMainWindow has special behavior for the central widget that a QDialog does not. To achieve the desired behavior you need to create a layout, add the text area to the layout and assign the layout to the dialog.
Just to add a little note about this - I was trying to have a child window spawned from an application, which is a QDialog, containing a single QTextEdit as a child/content - and I wanted the QTextEdit to resize automatically whenever the QDialog window size changes. This seems to have done the trick for me with PyQt4:
def showTextWindow(self):
#QVBox, QHBox # don't exist in Qt4
dialog = QDialog(self)
#dialog.setGeometry(QRect(100, 100, 400, 200))
dialog.setWindowTitle("Title")
dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
textbox = QTextEdit(dialog)
textbox.setReadOnly(True)
textbox.setMinimumSize(QSize(400, 400*0.75))
textbox.setText("AHAAA!")
# this seems enough to have the QTextEdit
# autoresize to window size changes of dialog!
layout = QHBoxLayout(dialog)
layout.addWidget(textbox)
dialog.setLayout(layout)
dialog.exec_()
I had looked at using a QLayout before but had no luck. I was trying to do something like
dialog.setLayout(some_layout)
but I couldn't get that approach to work so I gave up.
My mistake was that I was trying to pass the layout to the dialog when I should have been passing the dialog to the layout.
Adding the lines
layout = QVBoxLayout(self)
layout.add(everything)
to the end of TestDialog.__init__ fixes the problem.
Thanks to Monjardin for prompting me to reconsider layouts.
Check out Python QT Automatic Widget Resizer It's suppose to work well.