Pyside GUI function overwrite issue - python

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.

Related

QVideoWidget and QStackedWidget creating problem in PySide6

I am trying to build a GUI using PySide6 on Windows 10 - Python V 3.10.2.
Basically, I wanted to create a vertical box on left with buttons to switch between the stacked widgets. And a video widget with play button & scroll bar on the right side with a stacked widget underneath the video widget. On the stacked widget, I intend to put some buttons which will link files to play on the video widget.
The Problem: The video widget does works perfectly when commenting out the stacked widget. However, if I add the stacked widget, sound does play nicely but the videowidget can't be seen.
See the code snippet below.
class mainwindow(QMainWindow):
def __init__(self):
super().__init__()
self.audio = QAudioOutput()
self.video = QVideoWidget()
self.player = QMediaPlayer()
self.player.setAudioOutput(self.audio)
self.player.setVideoOutput(self.video)
side_layout = QVBoxLayout()
side_layout.addWidget(QLabel('First Label'))
side_layout.addWidget(QPushButton('First Button'))
# I have not named buttons for now for conciseness.
vid_control_layout = QHBoxLayout()
play_btn = QPushButton('Play')
play_btn.clicked.connect(self.play_video)
vid_control_layout.addWidget(play_btn)
vid_control_layout.addWidget(QSlider(orientation = Qt.Horizontal))
stack_widget = QStackedWidget()
stack_widget.addWidget(QWidget())
stack_widget.addWidget(QWidget())
video_layout = QVBoxLayout()
video_layout.addWidget(self.video)
video_layout.addLayout(vid_control_layout)
video_layout.addWidget(stack_widget)
mainlayout = QHBoxLayout()
mainlayout.addLayout(side_layout)
mainlayout.addLayout(video_layout)
mainwidget = QWidget()
mainwidget.setLayout(mainlayout)
self.setCentralWidget(mainwidget)
def play_video(self):
self.player.setSource('111.mp4')
self.player.play()
app = QApplication(sys.argv)
win = mainwindow()
win.show()
sys.exit(app.exec())
I am a self learner of Python and started learning PyQt5 quite recently. As there was too many version problem in PyQt5 and QMediaPlayer, I switched to PySide6.
Let me know if this detail will help in fixing the problem.

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()

Button not displayed in the right place

I am using PyQt to create a desktop application. I am trying to create a button using hbox and vbox, but it doesn't display unless I give the specific command:
button1 = QtGui.QPushButton("Exit", self)
But, by doing this, the vbox and hbox functionality doesn't seem to function.
I need the button to be on the bottom-right corner of the window, which stays there even after window-resize.
With this code, it is positioned on the top-left corner.
from PyQt4 import QtGui, QtCore
import sys
class Trial(QtGui.QMainWindow):
def __init__(self):
super(Trial,self).__init__()
self.createUI()
def createUI(self):
button1 = QtGui.QPushButton("Exit",self)
button1.clicked.connect(self.close)
hbox = QtGui.QHBoxLayout()
hbox.addStretch(1) #stretches it to the right end of the page
hbox.addWidget(button1)
vbox = QtGui.QVBoxLayout()
vbox.addStretch(1) #stretches it to the bottom end of the page
vbox.addLayout(hbox)
self.setLayout(vbox)
button1.resize(button1.sizeHint())
self.setGeometry(300,200,750,450)
self.setWindowTitle('Testing')
self.show()
def main():
app= QtGui.QApplication(sys.argv)
w=Trial()
sys.exit(app.exec_())
if __name__=='__main__':
main()
If I use button1.move(420, 400), it moves the button to the position I want, but it doesn't stay there when I re-size the application window.
The example code doesn't work because you are trying to set a layout on the main window, which already has a layout.
Instead, you need to add a central widget, and then set the layout on that:
def createUI(self):
self.setCentralWidget(QtGui.QWidget(self))
...
vbox.addLayout(hbox)
self.centralWidget().setLayout(vbox)
self.setGeometry(300,200,750,450)
...

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.

PyQt: LineEdit widget's placement inside of FormLayout

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)

Categories