how to copy frame from tab to new tab in tabwidget pyqt5? - python

How to copy tab1 frame to new tab which is dynamically added using QPushButton and addTab function.
Trying to create gui with "Insert Tab" button that will add new tab with predefined frame and settings,
but its replacing frame from tab1 to new tab if I go back to tab one its missing the frame which i used in new tab.
How can I copy the widgets instead of moving it while adding new tab?
ui file:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1120</width>
<height>850</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QTabWidget" name="tabWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>130</y>
<width>1121</width>
<height>721</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(253, 255, 242);</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Tab 1</string>
</attribute>
<widget class="QWidget" name="widget" native="true">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1111</width>
<height>691</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 243, 242);</string>
</property>
<widget class="QFrame" name="frame_frame">
<property name="geometry">
<rect>
<x>700</x>
<y>210</y>
<width>171</width>
<height>80</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>30</x>
<y>30</y>
<width>47</width>
<height>13</height>
</rect>
</property>
<property name="text">
<string>Hello saqib</string>
</property>
</widget>
</widget>
</widget>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Tab 2</string>
</attribute>
</widget>
</widget>
<widget class="QPushButton" name="change">
<property name="geometry">
<rect>
<x>60</x>
<y>50</y>
<width>93</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>Change Text</string>
</property>
</widget>
<widget class="QPushButton" name="insert">
<property name="geometry">
<rect>
<x>220</x>
<y>50</y>
<width>93</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>Insert Tab</string>
</property>
</widget>
<widget class="QPushButton" name="remove">
<property name="geometry">
<rect>
<x>390</x>
<y>50</y>
<width>93</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>Remove Tab</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
python main:
import sys
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.uic import loadUi
from PySide2.QtCore import *
class MainWindow(QDialog):
def __init__(self):
super(MainWindow, self).__init__()
loadUi("tabtutorial.ui", self)
self.tabWidget.currentChanged.connect(self.tabChanged)
self.change.clicked.connect(self.changeTabText)
self.insert.clicked.connect(self.insertTab)
self.remove.clicked.connect(self.removeTab)
def tabChanged(self):
print("Tab was changed to ", self.tabWidget.currentIndex())
def changeTabText(self):
self.tabWidget.setTabText(0, "First tab")
self.tabWidget.setTabText(1, "Second tab")
def insertTab(self):
self.label.setText(QCoreApplication.translate("Dialog", "Hello test", None))
self.tabWidget.addTab(self.widget, "New Tab")
def removeTab(self):
self.tabWidget.removeTab(0)
# main
app = QApplication(sys.argv)
mainwindow = MainWindow()
widget = QtWidgets.QStackedWidget()
widget.addWidget(mainwindow)
widget.setFixedHeight(850)
widget.setFixedWidth(1120)
widget.show()
try:
sys.exit(app.exec_())
except:
print("Exiting")
Output:
this Tab1 have a frame with "Hello Saq" label under frame widget.
If I insert new tab (using the above code addTab(self.widget, "New Tab") function its adding the frame to new tab but now its missing in the Tab1
Is there any way to copy widget instead of moving it?

Related

Docking animation for right side doesn't reappear after size adjustment while floating

In my current layout, I have a table in a dock widget that is initially docked (right side). I adjust the contents of the QMainWindow by connecting a function to topLevelChanged() to fill the blank space while floating
self.log_dock.topLevelChanged.connect(self.resize_dock)
def resize_dock(self):
layout = self.tb_utils.findChild(QtWidgets.QLayout)
layout.setExpanded(True)
self.adjustSize()
This works wonderfully - however; after doing so - I'm not entirely sure how to get it to redock to it's original position, or animate to expand the window again. If I manually adjust the QMainWindow slightly, it will allow the dock - or it can be moved into another dock area, and then moved back into position - but this is not ideal.
EDIT: New program using minimal reproducible example
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QMainWindow, QLayout
import sys
gui = uic.loadUiType('dock_behavior.ui')[0]
class Window(QMainWindow, gui):
def __init__(self):
super(Window, self).__init__()
self.setupUi(self)
self._connectEvents()
def _connectEvents(self):
self.dockWidget.topLevelChanged.connect(self.resize_dock)
self.show_dock.toggled.connect(self.enable_dock)
def resize_dock(self):
self.adjustSize()
layout = self.toolBar.findChild(QLayout)
layout.setExpanded(True)
def enable_dock(self):
self.dockWidget.toggleViewAction().trigger()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
The GUI as produced by Qt Designer
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>825</width>
<height>600</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>500</width>
<height>600</height>
</size>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>19</x>
<y>19</y>
<width>461</width>
<height>541</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>461</width>
<height>541</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
<rect>
<x>19</x>
<y>19</y>
<width>411</width>
<height>501</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout"/>
</widget>
</widget>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="show_dock"/>
</widget>
<widget class="QDockWidget" name="dockWidget">
<property name="minimumSize">
<size>
<width>291</width>
<height>0</height>
</size>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents"/>
</widget>
<action name="show_dock">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Show / Hide Dock</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

How to access a button from Tab Widget in PyQt5

I have made a Tab Widget Window in my Main Window using Qt-Designer and I am trying to access a button in my 1st Tab.
This is my code.
import sys
from PyQt5 import QtCore, QtGui,uic,QtWidgets
class AddWindow(QtWidgets.QDialog):
def __init__(self):
super(AddWindow,self).__init__()
uic.loadUi('AddWindow.ui',self)
class MyApp(QtWidgets.QMainWindow):
def __init__(self):
super(MyApp,self).__init__()
uic.loadUi('MainWindow.ui',self)
self.AddButton.clicked.connect(self.Addwindow)
def printW(self):
print("hello")
def Addwindow(self):
addwindow=AddWindow()
addwindow.exec_()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
I just want to have my button on 1st tab (named print) connected with function printW So I can display something on screen.
here is my MainWindow.ui file.
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>756</width>
<height>549</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="AddButton">
<property name="geometry">
<rect>
<x>630</x>
<y>440</y>
<width>121</width>
<height>61</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
<underline>true</underline>
<strikeout>false</strikeout>
</font>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
<widget class="QPushButton" name="Next">
<property name="geometry">
<rect>
<x>170</x>
<y>420</y>
<width>121</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>Next</string>
</property>
</widget>
<widget class="QTabWidget" name="tabWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>50</y>
<width>711</width>
<height>311</height>
</rect>
</property>
<property name="currentIndex">
<number>2</number>
</property>
<widget class="QWidget" name="tab1">
<attribute name="title">
<string>Tab 1</string>
</attribute>
<widget class="QPushButton" name="print">
<property name="geometry">
<rect>
<x>190</x>
<y>100</y>
<width>101</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>print</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="tab2">
<attribute name="title">
<string>tab 2</string>
</attribute>
</widget>
<widget class="QWidget" name="tab3">
<attribute name="title">
<string>Page</string>
</attribute>
</widget>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>756</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
I have tried creating a class and accessing button but could not do it.

Pyside2 QAction triggers once automatically but not when user clicks the menu

I've created a simple GUI using qt designer and imported it into my python project. The main window comes up, and the menus/buttons are responsive, but I cannot manage to connect my QActions to custom functions (I did it for buttons though, and it works). The weird thing is that my custom function (on_action_clicked) is called once when I run the application, but not when I click on the menu items or icons of the toolbar (I tried connecting both). Below are the test codes. Am I missing something?
imbrowser3d.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>851</width>
<height>649</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QGraphicsView" name="gv_image">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>731</width>
<height>501</height>
</rect>
</property>
</widget>
<widget class="QScrollBar" name="sb_index">
<property name="geometry">
<rect>
<x>0</x>
<y>510</y>
<width>701</width>
<height>20</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QScrollBar" name="sb_zeta">
<property name="geometry">
<rect>
<x>0</x>
<y>530</y>
<width>701</width>
<height>20</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label_index">
<property name="geometry">
<rect>
<x>700</x>
<y>510</y>
<width>55</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>index</string>
</property>
</widget>
<widget class="QLabel" name="label_zeta">
<property name="geometry">
<rect>
<x>700</x>
<y>530</y>
<width>55</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>zeta</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>740</x>
<y>500</y>
<width>93</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>851</width>
<height>26</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="menu_open"/>
<addaction name="menu_save"/>
<addaction name="menu_load"/>
</widget>
<addaction name="menuFile"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="action_toolbar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="action_save_state"/>
</widget>
<action name="menu_open">
<property name="text">
<string>Open</string>
</property>
</action>
<action name="menu_save">
<property name="icon">
<iconset>
<normaloff>ui_icons/save_icon.png</normaloff>ui_icons/save_icon.png</iconset>
</property>
<property name="text">
<string>Save state</string>
</property>
</action>
<action name="menu_load">
<property name="text">
<string>Load state</string>
</property>
</action>
<action name="action_save_state">
<property name="icon">
<iconset>
<normaloff>ui_icons/save_icon.png</normaloff>ui_icons/save_icon.png</iconset>
</property>
<property name="text">
<string>Save state</string>
</property>
<property name="toolTip">
<string>Save state</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>
main.py
import sys
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication, QAction, QPushButton, QFileDialog
from PySide2.QtCore import QFile, QObject
class UiMainWindow(QObject):
def __init__(self, ui_file, parent=None):
super(UiMainWindow, self).__init__(parent)
ui_file = QFile(ui_file)
ui_file.open(QFile.ReadOnly)
loader = QUiLoader()
self.window = loader.load(ui_file)
ui_file.close()
self.btn = self.window.findChild(QPushButton, 'pushButton')
self.btn.clicked.connect(self.on_btn_clicked)
self.action_save = self.window.findChild(QAction, 'action_save_state')
self.action_save.triggered.connect(self.on_action_clicked('action clicked'))
self.window.show()
def on_action_clicked(self, txt):
print(txt)
def on_btn_clicked():
print('button clicked')
if __name__ == '__main__':
app = QApplication(sys.argv)
form = UiMainWindow('imbrowser3d.ui')
sys.exit(app.exec_())
You have 2 errors:
on_btn_clicked is a method of the class so it must have as the first parameter the instance, that is, self.
the connection is with the name of the function without evaluating, in your case the slot on_action_clicked you are evaluating it, so you are getting it printed at the beginning, for it there are 2 possible solutions: use partial or use a lambda function.
self.btn = self.window.findChild(QPushButton, 'pushButton')
self.btn.clicked.connect(self.on_btn_clicked)
self.action_save = self.window.findChild(QAction, 'action_save_state')
self.action_save.triggered.connect(partial(self.on_action_clicked, 'action clicked'))
# self.action_save.triggered.connect(lambda: self.on_action_clicked('action clicked')) # use lambda function
self.window.show()
def on_action_clicked(self, txt):
print(txt)
def on_btn_clicked(self):
print('button clicked')

PyQt5 close immediately when changing the status of QLineEdit

I decided to implement a simple version of GA algorithm. I firstly use Qt designer to create a .ui document which contains the component and layout of my GUI. Then try to connect it with the python, however, when comes to the self.dis_speed.insert(a), the window closes immediately. This is the whole code:
import sys
import random
import threading
import copy
from PyQt5 import QtCore, QtGui, uic, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton,QTextEdit,QAction, QLabel,QSpinBox,QLineEdit
from PyQt5.QtCore import pyqtSlot
qtCreatorFile = 'assignment1_gui.ui' # Enter file here.
class Ui(QtWidgets.QMainWindow):
size=0
fit_dict={}
individual=[]
def __init__(self,parent=None):
super(Ui,self).__init__(parent=parent)
s=uic.loadUi(qtCreatorFile, self)
self.show()
self.but_start.clicked.connect(self.start)
self.dis_speed=s.dis_speed
self.dis_fit=s.dis_fit
self.dis_speed.setReadOnly(True)
self.dis_fit.setReadOnly(True)
def init_ind(a):
indi = [[] for l in range(a)]
for i in range(0,a):
for j in range(0,28):
indi[i].append(chr(random.randint(32, 127)))
return indi
def evaluate_fit(target,a):
count=0
for i in range(0,len(target)):
if target[i]==a[i]:
count+=1
return count
return(28-Levenshtein.hamming(str(target),str(a)))
def mutate(a):
for i in range(0,len(a)):
if(random.random()<(1/len(a))):
a[i]=chr(random.randint(32, 127))
return a
def crossover(a,b):
c=list()
for i in range(0,len(a)):
if random.random()<0.5:
c.append(a[i])
else:
c.append(b[i])
return c
def ga_cross(self,individual,target):
ind=copy.deepcopy(Ui.individual)
speed=0
printf=0
while(1):
a=random.randint(0,Ui.size-1)
b=random.randint(0,Ui.size-1)
if Ui.fit_dict[a]>Ui.fit_dict[b]:
parent1=ind[a]
else:
parent1=ind[b]
a=random.randint(0,Ui.size-1)
b=random.randint(0,Ui.size-1)
if Ui.fit_dict[a]>Ui.fit_dict[b]:
parent2=ind[a]
else:
parent2=ind[b]
child=Ui.mutate(Ui.crossover(parent1,parent2))
a=random.randint(0,Ui.size-1)
b=random.randint(0,Ui.size-1)
if Ui.fit_dict[a]>Ui.fit_dict[b]:
ind[b]=child
Ui.fit_dict[b]=Ui.evaluate_fit(target,child)
else:
ind[a]=child
Ui.fit_dict[a]=Ui.evaluate_fit(target,child)
speed+=1
if child==target:
break
if printf%10==0:
res=max(Ui.fit_dict.items(), key=lambda x: x[1])
Ui.tex(str(speed),str(ind[res[0]]))
printf+=1
#pyqtSlot()
def tex(self,a,b):
self.dis_speed.end(False)
self.dis_speed.insert(a) #close immediately
self.dis_fit.end(False)
self.dis_fit.insert(b)
#pyqtSlot()
def start(self):
target=list('methinks it is like a weasel')
Ui.size=int(self.spin_size.value())
Ui.individual=Ui.init_ind(Ui.size)
s=range(0,Ui.size)
ss=[0 for i in range(0,Ui.size)]
Ui.fit_dict=dict(zip(s,ss))
for i in range(0,Ui.size):
Ui.fit_dict[i]=Ui.evaluate_fit(target,Ui.individual[i])
Ui.ga_cross(self,Ui.individual,target)
Ui.ga_nocross(self,Ui.individual,target)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = Ui()
window.show()
sys.exit(app.exec_())
The following page is the .ui document in XML format which can be directly copied.
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>957</width>
<height>717</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="lab_title">
<property name="geometry">
<rect>
<x>100</x>
<y>40</y>
<width>811</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>36</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Comparision between GA with&without crossover</string>
</property>
</widget>
<widget class="QSpinBox" name="spin_size">
<property name="geometry">
<rect>
<x>590</x>
<y>120</y>
<width>111</width>
<height>41</height>
</rect>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="displayIntegerBase">
<number>10</number>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>310</x>
<y>130</y>
<width>271</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<family>Times New Roman</family>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Please select the size of population:</string>
</property>
</widget>
<widget class="QPushButton" name="but_start">
<property name="geometry">
<rect>
<x>380</x>
<y>190</y>
<width>191</width>
<height>71</height>
</rect>
</property>
<property name="font">
<font>
<family>Wingdings 2</family>
<pointsize>24</pointsize>
</font>
</property>
<property name="text">
<string>START!</string>
</property>
</widget>
<widget class="QLabel" name="lab_nocr">
<property name="geometry">
<rect>
<x>30</x>
<y>330</y>
<width>241</width>
<height>51</height>
</rect>
</property>
<property name="font">
<font>
<family>Trajan Pro</family>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Speed of no crossover:</string>
</property>
</widget>
<widget class="QLabel" name="lab_cr">
<property name="geometry">
<rect>
<x>590</x>
<y>330</y>
<width>211</width>
<height>51</height>
</rect>
</property>
<property name="font">
<font>
<family>Trajan Pro</family>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Speed of crossover:</string>
</property>
</widget>
<widget class="QLabel" name="lab_nfit">
<property name="geometry">
<rect>
<x>130</x>
<y>410</y>
<width>111</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<family>YuMincho</family>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Fittest Now:</string>
</property>
</widget>
<widget class="QLabel" name="lab_fit">
<property name="geometry">
<rect>
<x>690</x>
<y>410</y>
<width>111</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<family>YuMincho</family>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Fittest Now:</string>
</property>
</widget>
<widget class="QLineEdit" name="dis_nspeed">
<property name="geometry">
<rect>
<x>270</x>
<y>340</y>
<width>51</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="dis_nfit">
<property name="geometry">
<rect>
<x>20</x>
<y>440</y>
<width>341</width>
<height>41</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="dis_speed">
<property name="geometry">
<rect>
<x>800</x>
<y>340</y>
<width>41</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="dis_fit">
<property name="geometry">
<rect>
<x>600</x>
<y>440</y>
<width>291</width>
<height>41</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>957</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

Maya PySide2 UI Get QLineEdit value

I am starting using QtCreator to create a UI for a little tool for Maya 2017. QtCreator gave me this .ui file :
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DockWidget</class>
<widget class="QDockWidget" name="DockWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>550</width>
<height>251</height>
</rect>
</property>
<property name="floating">
<bool>true</bool>
</property>
<property name="windowTitle">
<string>Attr Editor</string>
</property>
<widget class="QWidget" name="dockWidgetContents">
<widget class="QLineEdit" name="attr_value_textfield">
<property name="geometry">
<rect>
<x>130</x>
<y>128</y>
<width>391</width>
<height>20</height>
</rect>
</property>
<property name="toolTip">
<string>attr_value</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>227</x>
<y>20</y>
<width>97</width>
<height>25</height>
</rect>
</property>
<property name="font">
<font>
<family>Century Gothic</family>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Attr Editor</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>240</x>
<y>180</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Submit</string>
</property>
<property name="+command" stdset="0">
<string>submitCommand</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>20</x>
<y>130</y>
<width>80</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<family>Century Gothic</family>
</font>
</property>
<property name="text">
<string>Attribute Value</string>
</property>
</widget>
<widget class="QLineEdit" name="attr_name_textfield">
<property name="geometry">
<rect>
<x>130</x>
<y>78</y>
<width>391</width>
<height>20</height>
</rect>
</property>
<property name="toolTip">
<string>attr_name</string>
</property>
<property name="whatsThis">
<string/>
</property>
</widget>
<widget class="QPushButton" name="pushButton_3">
<property name="geometry">
<rect>
<x>440</x>
<y>180</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Cancel</string>
</property>
<property name="+command" stdset="0">
<string>cancelCommand</string>
</property>
</widget>
<widget class="QPushButton" name="display_button">
<property name="geometry">
<rect>
<x>30</x>
<y>180</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Display</string>
</property>
<property name="+command" stdset="0">
<string>displayCommand</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>20</x>
<y>80</y>
<width>82</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<family>Century Gothic</family>
</font>
</property>
<property name="text">
<string>Attribute Name</string>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
And I have this code wich displays my UI :
import maya.cmds as cmds
from PySide2.QtWidgets import *
from PySide2.QtCore import *
if cmds.window(main_window, ex = True):
cmds.deleteUI(main_window)
main_window = cmds.loadUI(uiFile = "C:/Users/thornydre/Desktop/attreditorui.ui")
cmds.showWindow(main_window)
def displayCommand(e):
print(attr_name_textfield.text())
print(attr_value_textfield.text())
def submitCommand(e):
attr_name = attr_name_textfield.text()
attr_value = attr_value_textfield.text()
is_string = False
try:
new_attr_value = float(attr_value)
if float(attr_value) % 1 == 0:
new_attr_value = int(attr_value)
except:
is_string = True
new_attr_value = attr_value
print(new_attr_value)
for name in cmds.ls(sl = True):
if is_string:
cmds.setAttr(name + "." + attr_name, new_attr_value, type = "string")
else:
cmds.setAttr(name + "." + attr_name, new_attr_value)
def cancelCommand(e):
cmds.deleteUI(main_window, window = True)
And if I click on my display_button, I have an error :
# Result: dockWidgetContents|display_button #
# Error: AttributeError: file <maya console> line 12: 'bool' object has no attribute 'attr_name_textfield' #
I tried to do it with a subclass of QtWidgets.QWidget as I found somewhere on the internet, but I don't really found any tutorial on how to build it properly:
from PySide2 import QtCore, QtGui, QtWidgets, QtUiTools
class Interface(QtWidgets.QWidget):
def __init__(self, parent = None):
super(Interface, self).__init__(parent)
ui_filename = "C:/Users/thornydre/Desktop/attreditorui.ui"
ui_file = QtCore.QFile(ui_filename)
ui_file.open(QtCore.QFile.ReadOnly)
self.ui = QtUiTools.QUiLoader().load(ui_file, parentWidget=self)
ui_file.close()
def connectInterface(self):
QtCore.QtObject.connect(self.displayCommand, QtCore.SIGNAL("clicked()"), self.displayCommandWin)
def displayCommand(self):
print(self.attr_name_textfield.text())
print(self.attr_value_textfield.text())
def main():
global ui
ui = Interface()
if __name__ == "__main__":
main()
Same thing here, the UI shows up, but really nothing happens with clicking on the display_button
Your second try with the class seems good but it's completely normal that you can't execute displayCommand, your button is not connected to your method.
Juste delete your connectInterface method, and right after ui_file.close() copy this:
self.ui.display_button.clicked.connect(self.displayCommand)
It should work better :) (and you have to use the eyllanesc solution too to access to the widgets values)

Categories

Resources