I am trying to use this solution by #eyllanesc:
pyqt qtabwidget horizontal tab and horizontal text in QtDesigner.
My main window has a QStackedWidget in which one of the pages is the page with horizontal tabs. I used Qt designer to create a dialog with a tab widget, and set the tabPosition to West. Then I promoted the TabWidget like shown in the original post.
This is what the resulting window looks like. There are no outlines around the tabs, and the tabs are not clickable:
This is my main code:
import sys
from PySide.QtGui import *
from PySide.QtCore import *
from tabs import TabsUi_Dialog
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.mainMenuWidget = MainStack(self)
self.setCentralWidget(self.mainMenuWidget)
self.show()
class MainStack(QWidget):
def __init__(self,parent=None):
super(MainStack,self).__init__(parent)
self.initUI()
def initUI(self):
layout = QVBoxLayout(self)
self.stack = QStackedWidget(parent=self)
self.tabPage = TabPage()
#Add Pages to Stack
self.stack.addWidget(self.tabPage)
#Add Stack to Layout
self.stack.setCurrentWidget(self.tabPage)
layout.addWidget(self.stack)
class TabPage(QWidget):
def __init__(self,parent=None):
super(TabPage,self).__init__(parent)
self.tabs = TabsUi_Dialog()
self.tabs.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWin = MainWindow()
ret = app.exec_()
sys.exit( ret )
And this is the tabs.py file created after converting the Qt Designer UI file with py-uic:
from PySide import QtCore, QtGui
class TabsUi_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 300)
self.verticalLayout = QtGui.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.tabWidget = TabWidget(Dialog)
self.tabWidget.setTabPosition(QtGui.QTabWidget.West)
self.tabWidget.setObjectName("tabWidget")
self.tab = QtGui.QWidget()
self.tab.setObjectName("tab")
self.tabWidget.addTab(self.tab, "")
self.tab_2 = QtGui.QWidget()
self.tab_2.setObjectName("tab_2")
self.tabWidget.addTab(self.tab_2, "")
self.verticalLayout.addWidget(self.tabWidget)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QtGui.QApplication.translate("Dialog", "Tab 1", None, QtGui.QApplication.UnicodeUTF8))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QtGui.QApplication.translate("Dialog", "Tab 2", None, QtGui.QApplication.UnicodeUTF8))
from tabwidget import TabWidget
Related
I'm trying to make a GUI that, once you press a button a scrollArea would dynamically get updated. I tried using QThread to not lock the GUI and to show the user the scrollArea as it gets populated with elements.
I made a thread worker class where inside a loop I'm creating the elements for the scrollArea.The elements are put on a QVBoxLayout and I'm trying to pass that layout to my GUI scrollArea using a signal of type QObject.
I'm receiving this error: QObject::setParent: Cannot set parent, new parent is in a different thread
I don't know what to do to solve this
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class WorkerThread(QThread):
my_signal = pyqtSignal(QObject)
def run(self):
top_layout = QtWidgets.QVBoxLayout()
for i in range(2500):
group_box = QtWidgets.QGroupBox()
group_box.setTitle('box {0}'.format(i))
label = QtWidgets.QLabel()
label.setText('label {0}'.format(i))
layout = QtWidgets.QHBoxLayout(group_box)
layout.addWidget(label)
top_layout.addWidget(group_box)
self.my_signal.emit(top_layout)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(640, 480)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(520, 30, 71, 51))
self.pushButton.setObjectName("pushButton")
self.scrollArea = QtWidgets.QScrollArea(self.centralwidget)
self.scrollArea.setGeometry(QtCore.QRect(0, 90, 511, 461))
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 505, 455))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
MainWindow.setCentralWidget(self.centralwidget)
self.pushButton.clicked.connect(self.click)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "add"))
def click(self):
self.worker = WorkerThread()
self.worker.start()
self.worker.my_signal.connect(self.update_scrollArea)
def update_scrollArea(self, top_layout):
top_widget = QtWidgets.QWidget()
top_widget.setLayout(top_layout)
self.scrollArea.setWidget(top_widget)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
I've had problems with creating PyQt5 objects in threads in the past, and one option for you would be to use a timer instead.
class Ui_MainWindow(object):
def __init__(self):
self.timer = QtCore.QBasicTimer()
self.timer.start(250, self)
self.i = 0
def timerEvent(self, event):
if self.i < 2500:
self.i+=1
top_layout = QtWidgets.QVBoxLayout()
group_box = QtWidgets.QGroupBox()
group_box.setTitle('box {0}'.format(i))
label = QtWidgets.QLabel()
label.setText('label {0}'.format(i))
layout = QtWidgets.QHBoxLayout(group_box)
layout.addWidget(label)
top_layout.addWidget(group_box)
self.my_signal.emit(top_layout)
def setupUi(self, MainWindow):
...
This way you will interrupt the main loop once every 250msec to update one loop iteration at a time and you will not freeze up the GUI.
In my main program, I have a Dock widget (Vertical layout) containing a TabWidget (layouts added per tab). In my first tab I have added a static table, which resizes with the dock.
I am trying to allow the user to dynamically add a tab by importing a TableWidget design from another file into a tab; however, I am having trouble getting the layout to mimic the first tab.
Below is my code. I can make the table appear in the freshly made tab, just not fully adjust to the dock window.
My python start file:
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import mainwindow, sys, os, PyQt5, resources, dataTable
class dataForm(QtWidgets.QWidget, dataTable.Ui_Form)
def __init__(self, parent=None):
super(dataForm, self).__init__(parent)
self.setupUi(self)
class Example(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.setupUi(self)
self.shortcut.activated.connect(self.addTabs)
def Resolution(self):
app = QtWidgets.QApplication([])
resolution = app.desktop().screenGeometry()
width, height = resolution.width(), resolution.height()
self.setMaximumSize(QtCore.QSize(width, height))
def addTabs(self):
self.DataSets.setUpdatesEnabled(True)
self.tab = QtWidgets.QWidget()
self.tab.setAutoFillBackground(False)
self.tab.setObjectName("userAdded")
pages = self.count()
# Set the tab layout
self.tableLayout = QtWidgets.QVBoxLayout(self.tab)
self.tableLayout.setContentsMargins(1, 0, 1, 0)
self.tableLayout.setSpacing(0)
self.tableLayout.setObjectName("tableGrid")
# Add table to the new tab widget
self.table = dataForm(self.tab)
# Add table to layout
self.tableLayout.addWidget(self.table)
self.tableLayout.addStretch()
# Add the tab and go to that location
self.DataSets.insertTab((pages-1), self.tab, "Set %d" %(pages))
self.DataSets.setCurrentIndex(pages-1)
def main():
app = QtWidgets.QApplication(sys.argv)
form = Example()
form.showMaximized()
app.exec_()
if __name__ == '__main__':
main()
and my dataTable.ui form:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(242, 450)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
Form.setSizePolicy(sizePolicy)
self.tableWidget = QtWidgets.QTableWidget(Form)
self.tableWidget.setGeometry(QtCore.QRect(1, 0, 240, 450))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.tableWidget.sizePolicy().hasHeightForWidth())
self.tableWidget.setSizePolicy(sizePolicy)
self.tableWidget.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
self.tableWidget.setAutoFillBackground(True)
self.tableWidget.setStyleSheet("QHeaderView::section { background-color:rgb(140, 200, 172)};\n"
"")
self.tableWidget.setFrameShape(QtWidgets.QFrame.Panel)
self.tableWidget.setFrameShadow(QtWidgets.QFrame.Plain)
self.tableWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContentsOnFirstShow)
self.tableWidget.setDragEnabled(True)
self.tableWidget.setAlternatingRowColors(True)
self.tableWidget.setGridStyle(QtCore.Qt.SolidLine)
self.tableWidget.setRowCount(35)
self.tableWidget.setColumnCount(10)
self.tableWidget.setObjectName("tableWidget")
item = QtWidgets.QTableWidgetItem()
brush = QtGui.QBrush(QtGui.QColor(50, 0, 0))
brush.setStyle(QtCore.Qt.NoBrush)
item.setForeground(brush)
self.tableWidget.setItem(0, 1, item)
self.tableWidget.horizontalHeader().setCascadingSectionResizes(False)
self.tableWidget.horizontalHeader().setDefaultSectionSize(70)
self.tableWidget.horizontalHeader().setHighlightSections(True)
self.tableWidget.horizontalHeader().setMinimumSectionSize(39)
self.tableWidget.verticalHeader().setVisible(True)
self.tableWidget.verticalHeader().setDefaultSectionSize(20)
self.tableWidget.verticalHeader().setSortIndicatorShown(True)
self.tableWidget.verticalHeader().setStretchLastSection(False)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.tableWidget.setSortingEnabled(True)
__sortingEnabled = self.tableWidget.isSortingEnabled()
self.tableWidget.setSortingEnabled(False)
self.tableWidget.setSortingEnabled(__sortingEnabled)
I'm pretty close, I think. Any suggestions?
Edit: Updated code to make the dataTable classified as a QWidget & passed self.tab as its parent in def AddTabs. Also, I added a part of the layout of AddTabs that was cut out accidentally.
I am trying to get stdout and error messages to show on my main window. The window is by pyqt and made via designer. I have a QTextEdit on it. This is where the output should show itself. Also I have a dialog box (again made via designer) where i set some settings for my program before running it. The dialog box is opened like this:
def open_settings(self):
dialog = SettingsDialog()
dialog.open_settings_tab() # its on a tab widget
I already read and used the info on these links to achieve my goal:
Print out python console output to Qtextedit
How to capture output of Python's interpreter and show in a Text widget?
Both are pretty much the same with different object names. The issue I'm having is that whenever I open a dialog box and return to the main window the stdout no longer shows itself on the QTextEdit. Instead it goes back to showing itself on Sublime Editor.
I believe it has something to do with the class instancing.
Here is how the Dialog class starts:
class SettingsDialog(QDialog):
def __init__(self, parent=None):
super(SettingsDialog, self).__init__(parent)
self.ui = Ui_SettingsDialog()
self.ui.setupUi(self)
and finally here is how my main window (form) class starts:
class MyForm(QMainWindow):
def __init__(self, parent=None):
super(MyForm, self).__init__(parent)
# Install the custom output stream
sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)
self.ui = Ui_MyForm()
self.ui.setupUi(self)
Any ideas of why the stdout stops working (in qtextedit) once i go into the dialog screen and come back?
NEW Update:
The code is very long. I made a small program thats showing the issue:
PS: I found that the problem is related with this line shown below:
self.ui.pushButton_path.clicked.connect(Form(self).change_path)
if i comment it out the problem goes away.. But I need to call that function (which opens a QDialog, from the main form). What is the proper way?
main:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtGui import QTextCursor
from ui_form import Ui_Form
from ui_dialog import Ui_Dialog
class EmittingStream(QObject): # test
textWritten = pyqtSignal(str)
def write(self, text):
self.textWritten.emit(str(text))
class Form(QMainWindow):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
# Install the custom output stream
sys.stdout = EmittingStream(textWritten=self.normalOutputWritten) # test
self.ui = Ui_Form()
self.ui.setupUi(self)
self.ui.pushButton_open.clicked.connect(self.open_dialog)
self.ui.pushButton_text.clicked.connect(self.test_write)
def __del__(self): # test
# Restore sys.stdout
sys.stdout = sys.__stdout__
def normalOutputWritten(self, text): # test
"""Append text to the QTextEdit."""
# Maybe QTextEdit.append() works as well, but this is how I do it:
# self.ui.tEdit_cli.insertPlainText(text)
cursor = self.ui.textEdit.textCursor()
cursor.movePosition(QTextCursor.End)
cursor.insertText(text)
self.ui.textEdit.setTextCursor(cursor)
self.ui.textEdit.ensureCursorVisible()
def open_dialog(self):
dialog = Dialog()
dialog.open_tab()
def test_write(self):
print("something written")
def change_path(self):
pass
class Dialog(QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.ui.pushButton_close.clicked.connect(self.close_dialog)
self.ui.pushButton_path.clicked.connect(Form(self).change_path) # this is what causes the issue. but i need to use it!
def open_tab(self):
self.ui.tabWidget.setCurrentIndex(0)
self.exec_()
def close_dialog(self):
self.close()
def main():
app = QApplication(sys.argv)
form = Form()
form.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
ui_dialog:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'dialog.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 300)
self.horizontalLayout = QtWidgets.QHBoxLayout(Dialog)
self.horizontalLayout.setObjectName("horizontalLayout")
self.tabWidget = QtWidgets.QTabWidget(Dialog)
self.tabWidget.setObjectName("tabWidget")
self.tab = QtWidgets.QWidget()
self.tab.setObjectName("tab")
self.pushButton_close = QtWidgets.QPushButton(self.tab)
self.pushButton_close.setGeometry(QtCore.QRect(100, 80, 211, 131))
self.pushButton_close.setObjectName("pushButton_close")
self.pushButton_path = QtWidgets.QPushButton(self.tab)
self.pushButton_path.setGeometry(QtCore.QRect(30, 30, 75, 23))
self.pushButton_path.setObjectName("pushButton_path")
self.tabWidget.addTab(self.tab, "")
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.tabWidget.addTab(self.tab_2, "")
self.horizontalLayout.addWidget(self.tabWidget)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton_close.setText(_translate("Dialog", "close"))
self.pushButton_path.setText(_translate("Dialog", "path"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Dialog", "Tab 1"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("Dialog", "Tab 2"))
"""
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
"""
ui_form:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'form.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(Form)
self.centralwidget.setObjectName("centralwidget")
self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit.setGeometry(QtCore.QRect(90, 230, 601, 271))
self.textEdit.setObjectName("textEdit")
self.pushButton_open = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_open.setGeometry(QtCore.QRect(140, 80, 241, 81))
self.pushButton_open.setObjectName("pushButton_open")
self.pushButton_text = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_text.setGeometry(QtCore.QRect(440, 80, 251, 81))
self.pushButton_text.setObjectName("pushButton_text")
Form.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(Form)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
Form.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(Form)
self.statusbar.setObjectName("statusbar")
Form.setStatusBar(self.statusbar)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "MainWindow"))
self.pushButton_open.setText(_translate("Form", "open dialog"))
self.pushButton_text.setText(_translate("Form", "write somthing"))
"""
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QMainWindow()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
"""
You must use the object to invoke a method, you must not use the class, so the instruction Form(self) is not valid.
You must make the connection where you can access the signal and the slot simultaneously, for example open_dialog would be a good place:
class Form(QMainWindow):
...
def open_dialog(self):
dialog = Dialog(self)
dialog.ui.pushButton_path.clicked.connect(self.change_path) # +++
dialog.open_tab()
def test_write(self):
print("something written")
def change_path(self):
pass
class Dialog(QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.ui.pushButton_close.clicked.connect(self.close_dialog)
# self.ui.pushButton_path.clicked.connect(Form(self).change_path) ---
...
Defined a custom widget by extending a built-in QLineEdit by making it 'Double-Clickable':
class Clickable_LineEdit(QtGui.QLineEdit):
def __init__(self, type, parent=None):
super(DCLineEdit, self).__init__(parent)
def mouseDoubleClickEvent(self, event):
print "CLICK"
Now I can use this 'custom' Clickable_LineEdit widget to populate a main dialog window. It all works fine. But every time a double-click occurs it is registered OUTSIDE of main dialog window class... meaning all the main_dialog class's variables, all the data left behind and it is not available to Clickable_LineEdit class instance.
I wonder if it's possible to get doubleClick functionality from LineEdit without leaving a main dialog class.
EDITED LATER:
Here is modified example from a post below:
from PyQt4 import QtCore, QtGui
class Clickable_LineEdit(QtGui.QLineEdit):
def __init__(self, parent=None):
super(QtGui.QLineEdit, self).__init__(parent)
def mouseDoubleClickEvent(self, event):
print "CLICK"
class Ui_Dialog(QtGui.QWidget):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(348, 195)
self.lineEdit = Clickable_LineEdit(Dialog)
self.lineEdit.setGeometry(QtCore.QRect(50, 40, 113, 20))
self.lineEdit.setObjectName("lineEdit")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
def runOnDoubleClick(self):
print "DOUBLE CLICK"
import sys
def main():
app = QtGui.QApplication(sys.argv)
ex = Ui_Dialog()
ex.setupUi(ex)
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I have added a "runOnDoubleClick" function under a "Ui_Dialog()" class I would like to run every time a self.lineEdit widget is double-clicked (instead of mouseDoubleClickEvent() function). How would it be accomplished?
Well , according to what i understood , you want to a lineEdit that senses a doubleclick signal whenever lineEdit is doubleClicked .
from PyQt4 import QtCore, QtGui
class Clickable_LineEdit(QtGui.QLineEdit):
def __init__(self, parent=None):
super(QtGui.QLineEdit, self).__init__(parent)
def mouseDoubleClickEvent(self, event):
print "CLICK"
class Ui_Dialog(QtGui.QWidget):
def setupUi(self, Dialog):
Dialog.setObjectName(_fromUtf8("Dialog"))
Dialog.resize(348, 195)
self.lineEdit = Clickable_LineEdit(Dialog)
self.lineEdit.setGeometry(QtCore.QRect(50, 40, 113, 20))
self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
import sys
def main():
app = QtGui.QApplication(sys.argv)
ex = Ui_Dialog()
ex.setupUi(ex)
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
This seems to work for me .
I am trying to access all the buttons, labels, text widgets, etc inside nested QVBoxLayout and QHBoxLayout layouts using the children() method. But I am not getting the results I expect: I am only getting the layouts but not the buttons, labels, etc.
Is there a Pythonic way of iterating through all the nested layouts to obtain the buttons, labels, textedit, etc.?
Here is the part where I am having trouble:
for child in self.ui.gridLayout.children():
print "child_name:%s - type:%s" %(child.objectName(),type(child))
for grand_child in child.children():
print "gc_name:%s - type:%s" %(grand_child.objectName(),type(grand_child))
# never prints the buttons, labels, etc
for ggc in grand_child.children():
print "ggc_name:%s - type:%s" %(ggc.objectName(),type(ggc))
# never finds the QLabels
qreg = QRegExp('.+')
widgets = grand_child.findChildren(QLabel,qreg)
print widgets # prints None
Here is the whole code:
import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from mygui import Ui_Form
class MyApp(QtGui.QWidget):
def __init__(self,parent=None):
super(MyApp, self).__init__(parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.ui.pushButton_test.clicked.connect(self.click_button)
def click_button(self):
print "Printing layouts and widgets"
for child in self.ui.gridLayout.children():
print "child_name:%s - type:%s" %(child.objectName(),type(child))
for grand_child in child.children():
print "gc_name:%s - type:%s" %(grand_child.objectName(),type(grand_child))
# never prints
for ggc in grand_child.children():
print "ggc_name:%s - type:%s" %(ggc.objectName(),type(ggc))
qreg = QRegExp('.+')
widgets = grand_child.findChildren(QLabel,qreg)
print widgets # prints None
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MyApp()
myapp.show()
sys.exit(app.exec_())
And here's mygui.py:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'mygui.ui'
#
# Created: Thu Mar 28 14:07:12 2013
# by: PyQt4 UI code generator 4.9.1
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(454, 323)
self.gridLayout = QtGui.QGridLayout(Form)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.lineEdit = QtGui.QLineEdit(Form)
self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
self.horizontalLayout.addWidget(self.lineEdit)
self.pushButton_2 = QtGui.QPushButton(Form)
self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
self.horizontalLayout.addWidget(self.pushButton_2)
self.verticalLayout.addLayout(self.horizontalLayout)
self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
self.label_2 = QtGui.QLabel(Form)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.horizontalLayout_2.addWidget(self.label_2)
self.label = QtGui.QLabel(Form)
self.label.setObjectName(_fromUtf8("label"))
self.horizontalLayout_2.addWidget(self.label)
self.verticalLayout.addLayout(self.horizontalLayout_2)
self.textEdit = QtGui.QTextEdit(Form)
self.textEdit.setObjectName(_fromUtf8("textEdit"))
self.verticalLayout.addWidget(self.textEdit)
self.pushButton_test = QtGui.QPushButton(Form)
self.pushButton_test.setObjectName(_fromUtf8("pushButton_test"))
self.verticalLayout.addWidget(self.pushButton_test)
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_2.setText(QtGui.QApplication.translate("Form", "PushButton", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("Form", "TextLabel", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("Form", "TextLabel", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_test.setText(QtGui.QApplication.translate("Form", "Print All Widgets", None, QtGui.QApplication.UnicodeUTF8))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Form = QtGui.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
I appreciate your help and input.
Paul
I realized that all the widgets can be accessed from self. Here is the final code I used:
wtypes = [QPushButton,QLabel,QTextEdit]
qreg = QRegExp(r'.*')
mywidgets = {}
for t in wtypes:
mywidgets[t] = self.findChildren(t,qreg)
for button in mywidgets[QPushButton]:
print "button:", button.objectName()
for label in mywidgets[QLabel]:
print "label:", label.objectName()