resizable QtDialog

Need help, or want to share a macro? Post here!
User avatar
Zolko
Posts: 1101
Joined: Mon Dec 17, 2018 10:02 am

resizable QtDialog

Postby Zolko » Wed Jan 22, 2020 10:45 am

Hello,

I use some (many) QtGui.QDialog type windows, with QtGui.QPushButton, QtGui.QLabel, QtGui.QLineEdit... this sort of basic things, and until now I hard-coded all sizes and positions. Like:

Code: Select all

self.linkName = QtGui.QLineEdit(self)
self.linkName.setText( self.selectedLink.Name )
self.linkName.setMinimumSize(200, 1)
self.linkName.move(35,50)

self.OKButton = QtGui.QPushButton('OK', self)
self.OKButton.move(460, 600)
I know this is not the proper way to do it, and it should be done with frames and flows and alignments. Also, I don't want to go to a separate QtDesigner UI file, because for the simple UI it's easier to have the UI with the code. It's debatable, but today that's not the debate.

What is the proper way to draw a QtGui.QDialog with widgets in a dynamic/resizable way ?
Could someone point me to templates ?

As an example of what I would like to replicate (but better) is this command:

https://github.com/Zolko-123/FreeCAD_As ... tionLib.py
try the Assembly4 workbench for FreCAD v0.19
install with Tools > Addon Manager > Assembly4 — tutorials here and here
mario52
Posts: 3232
Joined: Wed May 16, 2012 2:13 pm

Re: resizable QtDialog

Postby mario52 » Wed Jan 22, 2020 2:03 pm

hi

with QtGui.QVBoxLayout()

extract on my macro FCInfo (.QVBoxLayout() is added by rmu75) installable by AddonManager

Code: Select all

        vbox = QtGui.QVBoxLayout()
        self.scrollAreaWidgetContents_2.setLayout(vbox)

        grid = QtGui.QGridLayout()
        self.GBox_001_Document = QtGui.QGroupBox(self.scrollAreaWidgetContents_2)
        self.GBox_001_Document.setObjectName(_fromUtf8("GBox_001_Document"))
        self.GBox_001_Document.setLayout(grid)
        vbox.addWidget(self.GBox_001_Document)


mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting, Dialog creation. My macros on Gist.github.
User avatar
Zolko
Posts: 1101
Joined: Mon Dec 17, 2018 10:02 am

Re: resizable QtDialog

Postby Zolko » Thu Jan 23, 2020 7:52 am

mario52 wrote:
Wed Jan 22, 2020 2:03 pm
with QtGui.QVBoxLayout()
thanx, will try
try the Assembly4 workbench for FreCAD v0.19
install with Tools > Addon Manager > Assembly4 — tutorials here and here
triplus
Posts: 9475
Joined: Mon Dec 12, 2011 4:45 pm

Re: resizable QtDialog

Postby triplus » Thu Jan 23, 2020 9:52 pm

As Mario suggested using layouts is what you are after.
mario52
Posts: 3232
Joined: Wed May 16, 2012 2:13 pm

Re: resizable QtDialog

Postby mario52 » Thu Jan 23, 2020 10:28 pm

hi

just finished little example PySide2 (4 button) and run well

Code: Select all

# -*- coding: utf-8 -*-

import PySide2
from PySide2 import QtGui ,QtCore, QtWidgets
from PySide2.QtGui import *
from PySide2.QtCore import *

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(481, 235)

        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        self.pushButton_1 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_1.setObjectName("pushButton_1")
        self.pushButton_1.clicked.connect(self.on_pushButton_1_clicked)
        self.gridLayout.addWidget(self.pushButton_1, 0, 0, 1, 1)    # modify the value for modify position

        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_2.clicked.connect(self.on_pushButton_2_clicked)
        self.gridLayout.addWidget(self.pushButton_2, 0, 1, 1, 1)

        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setObjectName("pushButton_3")
        self.pushButton_3.clicked.connect(self.on_pushButton_3_clicked)
        self.gridLayout.addWidget(self.pushButton_3, 0, 2, 1, 1)

        self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_4.setObjectName("pushButton_4")
        self.pushButton_4.clicked.connect(self.on_pushButton_4_clicked)
        self.gridLayout.addWidget(self.pushButton_4, 0, 3, 1, 1)

        MainWindow.setCentralWidget(self.centralwidget)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(u"Example gridLayout")
        self.pushButton_1.setText(u"pushButton_1")
        self.pushButton_2.setText(u"pushButton_2")
        self.pushButton_3.setText(u"pushButton_3")
        self.pushButton_4.setText(u"pushButton_4")

    def on_pushButton_1_clicked(self):
        App.Console.PrintMessage("pushButton_1"+"\n")

    def on_pushButton_2_clicked(self):
        App.Console.PrintMessage("pushButton_2"+"\n")

    def on_pushButton_3_clicked(self):
        App.Console.PrintMessage("pushButton_3"+"\n")

    def on_pushButton_4_clicked(self):
        App.Console.PrintMessage("pushButton_4"+"\n")


if __name__ == "__main__":
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()


EDIT:24/01/2020 14h59 Paris: adding connection in MacroCode

mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting, Dialog creation. My macros on Gist.github.
User avatar
Zolko
Posts: 1101
Joined: Mon Dec 17, 2018 10:02 am

Re: resizable QtDialog

Postby Zolko » Sat Jan 25, 2020 7:29 pm

mario52 wrote:
Wed Jan 22, 2020 2:03 pm
with QtGui.QVBoxLayout()
yeah, did-it, at least. Took me 1/2 day to understand how the Qt widgets work. And I still understand 1/2 of it (for example all this (self) stuff. Finally, what works, is to define a layout, add things to the layout, then create an empty widget and apply the layout to the widget:

Code: Select all

        self.formLayout = QtGui.QFormLayout(self)
        self.typeList = QtGui.QComboBox(self)
        self.formLayout.addRow(QtGui.QLabel('Type'),self.typeList)
...
        self.formWidget = QtGui.QWidget(self)
        self.formWidget.setLayout(self.formLayout)
and you can combine nested layouts in the main window in the same way. Still don't understand how the (self) things work, when they're necessary or destructive.
try the Assembly4 workbench for FreCAD v0.19
install with Tools > Addon Manager > Assembly4 — tutorials here and here
vocx
Posts: 5206
Joined: Thu Oct 18, 2018 9:18 pm

Re: resizable QtDialog

Postby vocx » Sat Jan 25, 2020 7:45 pm

Zolko wrote:
Sat Jan 25, 2020 7:29 pm
... Still don't understand how the (self) things work, when they're necessary or destructive.
You have to read a bit on how to use Python classes.

In Python the word "self" is used as a convention to refer to the class itself.

Code: Select all

class Something:
    self.variable = 0
    def function()
        return self.variable
    self.function()
Once you create an instance of your class "Something", this instance can access the defined variable, and the defined function.

Code: Select all

obj = Something()
print(obj.variable)
obj.function()
So the "self" keyword indicates the instance of the class that you are using, in this case, "obj".

Qt is full of classes, and those classes have tons of variables and functions. Occasionally, you need to pass a class name; if that is necessary, you can use the word "self" to indicate that you want to use this very same class.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
triplus
Posts: 9475
Joined: Mon Dec 12, 2011 4:45 pm

Re: resizable QtDialog

Postby triplus » Sat Jan 25, 2020 8:24 pm

Object-oriented programing paradigm.
openBrain
Posts: 4870
Joined: Fri Nov 09, 2018 5:38 pm

Re: resizable QtDialog

Postby openBrain » Sat Jan 25, 2020 8:50 pm

vocx wrote:
Sat Jan 25, 2020 7:45 pm

Code: Select all

class Something:
    self.variable = 0
    def function()
        return self.variable
    self.function()
:shock: :o This is probably one of the worst possible snippet to explain class variables... This will never work.
* Missing a semi-colon at the end of the def
* Instance variables can't be initialized directly under the class because self isn't defined there. Shall be in the __init__() function
* In the same way you can't call a function at class level
Below a proposal :

Code: Select all

class Person:
    className = "Person"

    def __init__(self, name):
        self.name = name

    def printName(self):
        print("My type is : " + self.className)
        print("My name is : " + self.name)

you = Person("you")
me = Person("me")
print("#####")
you.printName()
print("#####")
me.printName()
print("#####")
User avatar
Zolko
Posts: 1101
Joined: Mon Dec 17, 2018 10:02 am

Re: resizable QtDialog

Postby Zolko » Mon Jan 27, 2020 8:47 am

openBrain wrote:
Sat Jan 25, 2020 8:50 pm
Below a proposal :

Code: Select all

class Person:
    className = "Person"
...
some people tried to explain it to me before, and I sort-of, vaguely, understood the concept. They used drinks and beer and vine as examples though, much easier to grasp. But from concept to actually-being-able-to-use-it there is a whole world.
try the Assembly4 workbench for FreCAD v0.19
install with Tools > Addon Manager > Assembly4 — tutorials here and here