Convert Qt UI via pyside-uic

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
mea08kw
Posts: 82
Joined: Sun Oct 09, 2022 6:22 am

Convert Qt UI via pyside-uic

Post by mea08kw »

Hi Forum

I'm using FreeCAD 0.20 on Windows 11.

I have created a Qt UI which contains some pushbuttons and converted it into Python via pyside-uic.

The python code can be successfully executed in PyCharm, but it is failed in FreeCAD with Macro.

I appreciate that someone could have a look and sort it out.

Many thanks.

Mea08kw




The error message is

09:42:10 Traceback (most recent call last):
File "C:/Users/kit19/AppData/Roaming/FreeCAD/Macro/Test.FCMacro", line 71, in <module>
ui.setupUi(MainWindow)
File "C:/Users/kit19/AppData/Roaming/FreeCAD/Macro/Test.FCMacro", line 41, in setupUi
self.pushButton.clicked.connect(Dialog.slot1)
<class 'AttributeError'>: 'PySide2.QtWidgets.QMainWindow' object has no attribute 'slot1'
My Python code is:

Code: Select all


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

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        if not Dialog.objectName():
            Dialog.setObjectName(u"Dialog")
        Dialog.resize(896, 654)
        self.verticalLayout = QVBoxLayout(Dialog)
        self.verticalLayout.setObjectName(u"verticalLayout")

        self.pushButton = QPushButton(Dialog)
        self.pushButton.setObjectName(u"pushButton")
        self.pushButton.setGeometry(QtCore.QRect(400, 50, 175, 175))
        self.pushButton.setStyleSheet("QPushButton{border-image:url(casual.png)}"
                                      "QPushButton:hover{border-image: url(click.png)}"
                                      "QPushButton:pressed{border-image: url(casual.png)}")


        self.pushButton_3 = QPushButton(Dialog)
        self.pushButton_3.setObjectName(u"pushButton_3")
        self.pushButton_3.setGeometry(QtCore.QRect(400, 250, 175, 175))
        self.pushButton_3.setStyleSheet("QPushButton{border-image:url(formal.png)}"
                                        "QPushButton:hover{border-image: url(click.png)}"
                                        "QPushButton:pressed{border-image: url(formal.png)}")


        self.pushButton_2 = QPushButton(Dialog)
        self.pushButton_2.setObjectName(u"pushButton_2")
        self.pushButton_2.setGeometry(QtCore.QRect(400, 450, 175, 175))
        self.pushButton_2.setStyleSheet("QPushButton{border-image:url(sport.png)}"
                                        "QPushButton:hover{border-image: url(click.png)}"
                                        "QPushButton:pressed{border-image: url(sport.png)}")



        self.retranslateUi(Dialog)
        self.pushButton.clicked.connect(Dialog.slot1)
        self.pushButton_2.clicked.connect(Dialog.slot2)
        self.pushButton_3.clicked.connect(Dialog.slot4)

        QMetaObject.connectSlotsByName(Dialog)
    # setupUi

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Model Selection", None))
        self.pushButton.setText(QCoreApplication.translate("Dialog", u"Casual", None))
        self.pushButton_3.setText(QCoreApplication.translate("Dialog", u"Formal", None))
        self.pushButton_2.setText(QCoreApplication.translate("Dialog", u"Sport", None))
    # retranslateUi

class MainWindow(object):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)

    def slot1(self):
        print("Hello world1")

    def slot2(self):
        print("Hello world3")

    def slot4(self):
        print("Hello world2")

MainWindow = QtWidgets.QMainWindow()
ui = Ui_Dialog()
ui.setupUi(MainWindow)
MainWindow.show()


Last edited by mea08kw on Fri Dec 09, 2022 3:30 am, edited 1 time in total.
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Convert Qt UI via pyside-uic

Post by chennes »

When posting code here, please put it in "code" blocks, rather than "quote" blocks -- you've lost your indentation.
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Convert Qt UI via pyside-uic

Post by chennes »

I'm not entirely sure what you're trying to do here (I find some of your subclassing surprising), but the error you are getting is because the line:

Code: Select all

MainWindow = QtWidgets.QMainWindow()
creates a QMainWindow, which I don't think is what you want. Try replacing the final four lines, which currently read:

Code: Select all

MainWindow = QtWidgets.QMainWindow()
ui = Ui_Dialog()
ui.setupUi(MainWindow)
MainWindow.show()
with just:

Code: Select all

mw = MainWindow()
mw.show()
It's probably closer to what you intend.
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
mea08kw
Posts: 82
Joined: Sun Oct 09, 2022 6:22 am

Re: Convert Qt UI via pyside-uic

Post by mea08kw »

Hi Chennes

Thanks for pointing out the format of code when quoting.

I have modified it in my first thread.

The replacement of last 4 lines doesn't work for me.

Can you try the code on your FreeCAD platform?

What I want to do is quite simple, just create some button with some outputs when clicking them.

I did this successfully when loading UI, but I can't make it when converting the UI into python.

Mea08kw

chennes wrote: Fri Dec 09, 2022 2:36 am I'm not entirely sure what you're trying to do here (I find some of your subclassing surprising), but the error you are getting is because the line:

Code: Select all

MainWindow = QtWidgets.QMainWindow()
creates a QMainWindow, which I don't think is what you want. Try replacing the final four lines, which currently read:

Code: Select all

MainWindow = QtWidgets.QMainWindow()
ui = Ui_Dialog()
ui.setupUi(MainWindow)
MainWindow.show()
with just:

Code: Select all

mw = MainWindow()
mw.show()
It's probably closer to what you intend.
mea08kw
Posts: 82
Joined: Sun Oct 09, 2022 6:22 am

Re: Convert Qt UI via pyside-uic

Post by mea08kw »

Hi Chennes

Code: Select all


        self.pushButton.clicked.connect(Dialog.slot1)
        self.pushButton_2.clicked.connect(Dialog.slot2)
        self.pushButton_3.clicked.connect(Dialog.slot4)

If those three lines are commented out, it works like a window pops out, but the signal linked with this button is lost.

Best Regards,

Mea08kw
chennes wrote: Fri Dec 09, 2022 2:36 am I'm not entirely sure what you're trying to do here (I find some of your subclassing surprising), but the error you are getting is because the line:

Code: Select all

MainWindow = QtWidgets.QMainWindow()
creates a QMainWindow, which I don't think is what you want. Try replacing the final four lines, which currently read:

Code: Select all

MainWindow = QtWidgets.QMainWindow()
ui = Ui_Dialog()
ui.setupUi(MainWindow)
MainWindow.show()
with just:

Code: Select all

mw = MainWindow()
mw.show()
It's probably closer to what you intend.
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Convert Qt UI via pyside-uic

Post by chennes »

Let's try this: paste the following into a new macro in FreeCAD and run it, and let me know if it's doing what you want...

Code: Select all

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

class Ui_Dialog(object):
	def setupUi(self, Dialog):
		if not Dialog.objectName():
			Dialog.setObjectName(u"Dialog")
		Dialog.resize(896, 654)
		self.verticalLayout = QVBoxLayout(Dialog)
		self.verticalLayout.setObjectName(u"verticalLayout")
		
		self.pushButton = QPushButton(Dialog)
		self.pushButton.setObjectName(u"pushButton")
		self.pushButton.setGeometry(QtCore.QRect(400, 50, 175, 175))
		self.pushButton.setStyleSheet("QPushButton{border-image:url(casual.png)}"
		"QPushButton:hover{border-image: url(click.png)}"
		"QPushButton:pressed{border-image: url(casual.png)}")
		
		
		self.pushButton_3 = QPushButton(Dialog)
		self.pushButton_3.setObjectName(u"pushButton_3")
		self.pushButton_3.setGeometry(QtCore.QRect(400, 250, 175, 175))
		self.pushButton_3.setStyleSheet("QPushButton{border-image:url(formal.png)}"
		"QPushButton:hover{border-image: url(click.png)}"
		"QPushButton:pressed{border-image: url(formal.png)}")
		
		
		self.pushButton_2 = QPushButton(Dialog)
		self.pushButton_2.setObjectName(u"pushButton_2")
		self.pushButton_2.setGeometry(QtCore.QRect(400, 450, 175, 175))
		self.pushButton_2.setStyleSheet("QPushButton{border-image:url(sport.png)}"
		"QPushButton:hover{border-image: url(click.png)}"
		"QPushButton:pressed{border-image: url(sport.png)}")
		
		
		
		self.retranslateUi(Dialog)
		self.pushButton.clicked.connect(Dialog.slot1)
		self.pushButton_2.clicked.connect(Dialog.slot2)
		self.pushButton_3.clicked.connect(Dialog.slot4)
		
		QMetaObject.connectSlotsByName(Dialog)
	# setupUi
	
	def retranslateUi(self, Dialog):
		Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Model Selection", None))
		self.pushButton.setText(QCoreApplication.translate("Dialog", u" ", None))
		self.pushButton_3.setText(QCoreApplication.translate("Dialog", u" ", None))
		self.pushButton_2.setText(QCoreApplication.translate("Dialog", u" ", None))
	# retranslateUi

class MainWindow(QtWidgets.QMainWindow, Ui_Dialog):
	def __init__(self):
		super(MainWindow, self).__init__()
		self.setupUi(self)
	
	def slot1(self):
		print("Hello world1")
	
	def slot2(self):
		print("Hello world3")
	
	def slot4(self):
		print("Hello world2")

mw = MainWindow()
mw.show()
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
mea08kw
Posts: 82
Joined: Sun Oct 09, 2022 6:22 am

Re: Convert Qt UI via pyside-uic [solved]

Post by mea08kw »

Hi Chennes

Thanks a million, it works finally!!

I missed one argument in this line:

Code: Select all

class MainWindow(QtWidgets.QMainWindow, Ui_Dialog):
Mea08kw

chennes wrote: Fri Dec 09, 2022 4:07 am Let's try this: paste the following into a new macro in FreeCAD and run it, and let me know if it's doing what you want...

Code: Select all

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

class Ui_Dialog(object):
	def setupUi(self, Dialog):
		if not Dialog.objectName():
			Dialog.setObjectName(u"Dialog")
		Dialog.resize(896, 654)
		self.verticalLayout = QVBoxLayout(Dialog)
		self.verticalLayout.setObjectName(u"verticalLayout")
		
		self.pushButton = QPushButton(Dialog)
		self.pushButton.setObjectName(u"pushButton")
		self.pushButton.setGeometry(QtCore.QRect(400, 50, 175, 175))
		self.pushButton.setStyleSheet("QPushButton{border-image:url(casual.png)}"
		"QPushButton:hover{border-image: url(click.png)}"
		"QPushButton:pressed{border-image: url(casual.png)}")
		
		
		self.pushButton_3 = QPushButton(Dialog)
		self.pushButton_3.setObjectName(u"pushButton_3")
		self.pushButton_3.setGeometry(QtCore.QRect(400, 250, 175, 175))
		self.pushButton_3.setStyleSheet("QPushButton{border-image:url(formal.png)}"
		"QPushButton:hover{border-image: url(click.png)}"
		"QPushButton:pressed{border-image: url(formal.png)}")
		
		
		self.pushButton_2 = QPushButton(Dialog)
		self.pushButton_2.setObjectName(u"pushButton_2")
		self.pushButton_2.setGeometry(QtCore.QRect(400, 450, 175, 175))
		self.pushButton_2.setStyleSheet("QPushButton{border-image:url(sport.png)}"
		"QPushButton:hover{border-image: url(click.png)}"
		"QPushButton:pressed{border-image: url(sport.png)}")
		
		
		
		self.retranslateUi(Dialog)
		self.pushButton.clicked.connect(Dialog.slot1)
		self.pushButton_2.clicked.connect(Dialog.slot2)
		self.pushButton_3.clicked.connect(Dialog.slot4)
		
		QMetaObject.connectSlotsByName(Dialog)
	# setupUi
	
	def retranslateUi(self, Dialog):
		Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Model Selection", None))
		self.pushButton.setText(QCoreApplication.translate("Dialog", u" ", None))
		self.pushButton_3.setText(QCoreApplication.translate("Dialog", u" ", None))
		self.pushButton_2.setText(QCoreApplication.translate("Dialog", u" ", None))
	# retranslateUi

class MainWindow(QtWidgets.QMainWindow, Ui_Dialog):
	def __init__(self):
		super(MainWindow, self).__init__()
		self.setupUi(self)
	
	def slot1(self):
		print("Hello world1")
	
	def slot2(self):
		print("Hello world3")
	
	def slot4(self):
		print("Hello world2")

mw = MainWindow()
mw.show()
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Convert Qt UI via pyside-uic

Post by chennes »

Glad to hear it, good luck with the rest of your macro!
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
mea08kw
Posts: 82
Joined: Sun Oct 09, 2022 6:22 am

Re: Convert Qt UI via pyside-uic

Post by mea08kw »

chennes wrote: Fri Dec 09, 2022 4:26 am Glad to hear it, good luck with the rest of your macro!
Hi Chennes

One more thing I'm stuck with.

I put image file in Macro folder, but it seems that the image can not be read.

Best Regards,

Mea08kw

Code: Select all

self.pushButton_3.setStyleSheet("QPushButton{border-image:url(formal.png)}"
                                        "QPushButton:hover{border-image: url(click.png)}"
                                        "QPushButton:pressed{border-image: url(formal.png)}")
Post Reply