PyQt: LineEdit widget's placement inside of FormLayout - python

A QtGui.QLineEdit line_edit widget is placed inside of QtGui.QFormLayout Form layout using .addRow() method.
my_formLayout.addRow(my_label, my_lineEdit)
To make a line_edit widget to stick to a dialog window's edges (so it re-sizes with the dialog) tried using sizePolicy:
sizePolicy = my_lineEdit.sizePolicy()
sizePolicy.setHorizontalStretch(1)
my_lineEdit.setSizePolicy( sizePolicy )
There are no errors. But the line_edit widget still doesn't stick to the edges of the dialog... What could be wrong?

You shouldn't need to do anything.
This simple example resizes as necessary:
from PyQt4 import QtGui
class Dialog(QtGui.QDialog):
def __init__(self):
super(Dialog, self).__init__()
form = QtGui.QFormLayout(self)
label = QtGui.QLabel('Label', self)
edit = QtGui.QLineEdit(self)
form.addRow(label, edit)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Dialog()
window.setGeometry(500, 300, 300, 50)
window.show()
sys.exit(app.exec_())
UPDATE:
Okay, it seems the behaviour of QFormaLayout is platform-dependent. To quote from the docs:
Style based on the Mac OS X Aqua guidelines. Labels are right-aligned, the fields don't grow beyond their size hint, and the form is horizontally centered.
However, there is a setFieldGrowthPolicy method, which could be used to over-ride the default behaviour on Mac OSX. So try:
my_formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow)
or:
my_formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)

Try this: sizePolicy.setHorizontalPolicy(QSizePolicy.Expanding)

Related

PyQt5 - How to dynamically add widgets to window without layout

I've been trying to figure this one out, the reason I don't want to use a layout is because the widgets scale with the window when resizing and I want them to stay put, I have made it where I can drag and drop the widgets but with them being in a layout it messes it up, please can someone help me figure this out.
I Want to be able to add lets say a label widget, I want to have it where I can press a button and it will create a new label widget in my window, I have done this part already but I want to be able to add widgets without the layout.
You just have to set another widget that is part of the window (or the window itself) as parent and make it visible with the show method:
import random
import sys
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
button = QtWidgets.QPushButton("Add", self)
button.clicked.connect(self.handle_clicked)
self.resize(640, 480)
def handle_clicked(self):
pos = QtCore.QPoint(*random.sample(range(400), 2))
label = QtWidgets.QLabel(self)
label.move(pos)
label.setText("{}-{}".format(pos.x(), pos.y()))
label.show()
def main():
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()

How to resize a QColorDialog

Is it possible to resize a QColorDialog? I have been unable to get the window to resize appropriately. After the dialog is shown, it reverts to the default size.
An example:
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Window(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
push_Button = QPushButton()
layout.addWidget(push_Button)
push_Button.clicked.connect(self.button)
self.setLayout(layout)
def button(self):
color = QColorDialog(self)
color.resize(100,100)
print(color.size()) #Prints 100, 100
color.show()
print(color.size()) #Prints 551, 431
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
The QColorDialog has a fixed size, because it contains several custom widgets which aren't designed to be resizable. It is possble to override these constraints and allow for manual resizing like this:
color = QColorDialog(self)
color.setSizeGripEnabled(True)
color.layout().setSizeConstraint(QLayout.SetNoConstraint)
color.show()
However, as you will see, the layout quickly becomes messed up with even a little bit of resizing. I also found that beyond a certain point, the dialog will actually crash due to floating point exceptions. So I think you will either have to accept it as it is, or perhaps write your own color dialog.

Pyside GUI function overwrite issue

I am learning to make GUI's in PySide.
How do I re-size the buttons inside a QHBoxLayout()? I tried button_1.setFixedWidth() and button_1.setFixedHeight() these make the buttons non-scalable. button_1.move() also doesn't work.
Also I have created a function angles() which have Qlabel and QLineEdit, when I run the program, the button function is over-writing the angles function to display only buttons at right corner of the GUI.
And how to resize the length of the QLineEdit and for it to not extend the whole window?
import sys
from PySide.QtGui import *
from PySide.QtCore import *
class MainWindow(QMainWindow):
#GUI Layout
def __init__(self,parent = None):
super(MainWindow, self).__init__(parent)
widget = QWidget()
self.setCentralWidget(widget)
self.setWindowTitle("Example")
self.setGeometry(400, 100, 1500, 800)
self.angles()
self.makebuttons()
def angles(self):
central_widget = QWidget()
self.setCentralWidget(central_widget)
Rotation = QLabel('Rotation:')
Tilt = QLabel('Tilt:')
RoatationEdit = QLineEdit()
TiltEdit = QLineEdit()
grid = QGridLayout()
grid.setSpacing(2)
grid.addWidget(Rotation,1,0)
grid.addWidget(RoatationEdit, 1, 1)
grid.addWidget(Tilt,2,0)
grid.addWidget(TiltEdit, 2, 1)
central_widget.setLayout(grid)
def makebuttons(self):
central_widget = QWidget()
self.setCentralWidget(central_widget)
hbox = QHBoxLayout()
button_1 = QPushButton("Button 1",self)
button_1.move(0,30)
hbox.addStretch(1)
button_2 = QPushButton("Button 2",self)
hbox.addStretch(1)
hbox.addWidget(button_1)
hbox.addWidget(button_2)
vbox = QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)
central_widget.setLayout(vbox)
# central_widget.addLayout(vbox)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
If you want to resize use: button_1.setFixedSize({your scale}*button_1.size())
The makebuttons function creates another centralWidget by deleting all of the above, so you will not see what you did with angles.
To change the width of QLineEdit use {your QlineEdit} .setFixedWidth({your width})
I use Qt Designer for all of my Pyside GUI work, even if it's a fairly trivial program. It's much more than just a drag-and-drop WYSISYG tool. For things like push buttons in your example, you would be presented with a list of configurable properties including sizing parameters of the button as well as the ability to configure the layout.
So, my solution is to create your GUI in QT Designer then modify the layout there before using the pyside-uic tool to convert the code to python. Then just import the resulting python module into your code. From there you can still re-configure whatever you want later in your code if, for example, you need to change the appearance of your GUI during the course of your program.

How to install new QStyle for PyQt?

I'm writing a GUI in PyQt4 (and migrating to PyQt5). This is how I start my GUI:
if __name__== '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion')) # <- Choose the style
myGUI = MyMainWindow("First GUI")
app.exec_()
Default Styles in PyQt4 :
Apparently, PyQt4 has the following styles:
'Windows'
'WindowsXP'
'WindowsVista'
'Motif'
'CDE'
'Plastique'
'Cleanlooks'
Default Styles in PyQt5 :
PyQt5 has the following styles:
'Windows'
'WindowsXP'
'WindowsVista'
'Fusion'
Custom styles?
None of these styles has proper support for HiDpi displays (4k and the like). For example, scrollbars are too small( see this post: How to resize the scrollbar from a QTextEdit in PyQt?). And I didn't even mention the problems for those people with unsharp eyesight..
Do you know a style (preferably open-source) that provides good support for 4k displays or for people with eyesight problems?
If so, how can one download this style, and install it?
Thank you so much.
I got the answer (or let's say a workaround) through another question:
How to make Icon in QMenu larger (PyQt)?
The most straightforward way to create a new QStyle is deriving it from an existing one. PyQt provides the QProxyStyle class for that purpose. Below is the example that I've also given in the How to make Icon in QMenu larger (PyQt)? question. In this example, a custom QStyle is created (derived from "Fusion" style), and the custom style provides very big icons for the QMenu.
import sys
import os
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
# Create a custom "QProxyStyle" to enlarge the QMenu icons
#-----------------------------------------------------------
class MyProxyStyle(QProxyStyle):
pass
def pixelMetric(self, QStyle_PixelMetric, option=None, widget=None):
if QStyle_PixelMetric == QStyle.PM_SmallIconSize:
return 40
else:
return QProxyStyle.pixelMetric(self, QStyle_PixelMetric, option, widget)
# This is the main window class (with a simple QMenu implemented)
# ------------------------------------------------------------------
class TestWindow(QMainWindow):
def __init__(self):
super(TestWindow, self).__init__()
# 1. Set basic geometry and color.
self.setGeometry(100, 100, 400, 400)
self.setWindowTitle('Hello World')
palette = QPalette()
palette.setColor(QPalette.Window, QColor(200, 200, 200))
self.setPalette(palette)
# 2. Create the central frame.
self.centralFrame = QFrame()
self.centralFrame.setFrameShape(QFrame.NoFrame)
self.setCentralWidget(self.centralFrame)
# 3. Create a menu bar.
myMenuBar = self.menuBar()
fileMenu = myMenuBar.addMenu("&File")
testMenuItem = QAction(QIcon("C:\\my\\path\\myFig.png"), "&Test", self)
testMenuItem.setStatusTip("Test for icon size")
testMenuItem.triggered.connect(lambda: print("Menu item has been clicked!"))
fileMenu.addAction(testMenuItem)
# 4. Show the window.
self.show()
# Start your Qt application based on the new style
#---------------------------------------------------
if __name__== '__main__':
app = QApplication(sys.argv)
myStyle = MyProxyStyle('Fusion') # The proxy style should be based on an existing style,
# like 'Windows', 'Motif', 'Plastique', 'Fusion', ...
app.setStyle(myStyle)
myGUI = TestWindow()
sys.exit(app.exec_())
Just copy-paste the code snippet, and paste it in a *.py file. Of course, you should replace the path to the icon with a valid path on your local computer. Just provide a complete path ("C:..") to be 100% sure that Qt finds the icon drawing.
Try it out, and you should get the following window:

PyQt: Dialog's Minimize Window Button is Missing in OSX

A dialog created with:
class GUI(QtGui.QMainWindow):
def __init__(self):
super(GUI, self).__init__()
global dialog
dialog = QtGui.QDialog()
myGui = GUI()
is missing a minimize window button (OSX). It is there in Windows. Do I have to set some flag to display this missing controller? Please advise, Thanks in advance!
EDITED LATER:
I didn't try to solve a no-minimize-button issue with QtGui.QDialog(). But it appears I partically aware how to get that missing button using QtGui.QMainWindow.
Here is the simplest code illustrating a basic syntax:
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication(sys.argv)
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
myQWidget = QtGui.QWidget()
myBoxLayout = QtGui.QVBoxLayout()
myLineEdit = QtGui.QLineEdit("myLineEdit")
myBoxLayout.addWidget(myLineEdit)
myQWidget.setLayout(myBoxLayout)
self.setCentralWidget(myQWidget)
window = MainWindow()
window.show()
window.resize(480,320)
sys.exit(app.exec_())
A 'key' 'concept' behind QtGui.QMainWindow is that first we declare QWidget()
myQWidget = QtGui.QWidget()
to which we assign a 'main' layout:
myQWidget.setLayout(myBoxLayout)
Last step not to forget is to assign this QWidget() to dialog itself using:
self.setCentralWidget(myQWidget)
where 'self' is an instanced subclass of QtGui.QMainWindow.
I can't test this myself, but you could try setting these window flags:
dialog.setWindowFlags(dialog.windowFlags() |
QtCore.Qt.WindowMinimizeButtonHint |
QtCore.Qt.WindowSystemMenuHint)
(The WindowSystemMenuHint flag may not be necessary).
QtGui.QDialog does not offer a minimize button on any platform, but QtGui.QMainWindow does offer on each platform (Windows, Linux and OSX). You are creating a QDialog object and at the same time an object of GUI which is subclass of QMainWindow. If you write myGui.show() the window will offer you all three buttons (minimize, maximize/restore and close). But in case of dialog.show(), you will not have two of them (minimize and maximize/restore). It's Qt's limitation.

Categories