The code below create a simple QTreeWidget with two items one parented to another.
I want the items to be expanded from the begining (so the user doesn't have to click arrow to expand the items):
Here is how it looks by default:
And here is how I would like it to be (expanded: item "C" is visible):
What attribute needs to be set in order for this to work?
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])
class Tree(QtGui.QTreeWidget):
def __init__(self, *args, **kwargs):
super(Tree, self).__init__()
parentItem=QtGui.QTreeWidgetItem('P')
self.addTopLevelItem(parentItem)
childItem=QtGui.QTreeWidgetItem('C')
parentItem.insertChild(0, childItem)
self.show()
tree=Tree()
sys.exit(app.exec_())
You can use QTreeWidget.expandToDepth().
In your case:
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])
class Tree(QtGui.QTreeWidget):
def __init__(self, *args, **kwargs):
super(Tree, self).__init__()
parentItem=QtGui.QTreeWidgetItem('P')
self.addTopLevelItem(parentItem)
childItem=QtGui.QTreeWidgetItem('C')
parentItem.insertChild(0, childItem)
self.expandToDepth(0)
self.show()
tree=Tree()
sys.exit(app.exec_())
You could also use expandAll() to expand everything instead of only to certain depth.
Related
I'm using Qt Designer for design GUI to use in python, after designing my desired UI in Qt Designer, convert it to python code and then I changed generated code to do some action in my python code, but if I changed the UI with Qt Designer and convert it to python code again, I lost my previous changes on my code.
how can I solve the problem?
can we Spreading a Class Over Multiple Files in python to write code in other files?
To avoid having these problems it is advisable not to modify this file but to create a new file where we implement a class that uses that design.
For example, suppose you have used the MainWindow template in the design.ui file, then convert it to Ui_Design.py like to the following structure:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
[...]
def retranslateUi(self, MainWindow):
[...]
Then we will create a new file that we will call logic.py where we will create the file that handles the logic and that uses the previous design:
class Logic(QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
So even if you modify the design and generate the file again .py you will not have to modify the file of the logic.
To generalize the idea we must have the following rules but for this the logic class must have the following structure:
class Logic(PyQtClass, DesignClass):
def __init__(self, *args, **kwargs):
PyQtClass.__init__(self, *args, **kwargs)
self.setupUi(self)
PyQtClass: This class depends on the design chosen.
Template PyQtClass
─────────────────────────────────────────────
Main Window QMainWindow
Widget QWidget
Dialog with Buttons Bottom QDialog
Dialog with Buttons Right QDialog
Dialog with Without Buttons QDialog
DesignClass: The name of the class that appears in your design.
The advantage of this implementation is that you can implement all the logic since it is a widget, for example we will implement the solution closing pyqt messageBox with closeevent of the parent window :
class Logic(QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
def closeEvent(self, event):
answer = QtWidgets.QMessageBox.question(
self,
'Are you sure you want to quit ?',
'Task is in progress !',
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if answer == QtWidgets.QMessageBox.Yes:
event.accept()
else:
event.ignore()
The easiest way is to use the *.ui file directly in the python code, you don't need convert to *.py file every time you change the ui.
you can use this pseudo code in your project.
# imports
from PyQt5 import uic
# load ui file
baseUIClass, baseUIWidget = uic.loadUiType("MainGui.ui")
# use loaded ui file in the logic class
class Logic(baseUIWidget, baseUIClass):
def __init__(self, parent=None):
super(Logic, self).__init__(parent)
self.setupUi(self)
.
.
.
.
def main():
app = QtWidgets.QApplication(sys.argv)
ui = Logic(None)
ui.showMaximized()
sys.exit(app.exec_())
I'm using Qt Designer for design GUI to use in python, after designing my desired UI in Qt Designer, convert it to python code and then I changed generated code to do some action in my python code, but if I changed the UI with Qt Designer and convert it to python code again, I lost my previous changes on my code.
how can I solve the problem?
can we Spreading a Class Over Multiple Files in python to write code in other files?
To avoid having these problems it is advisable not to modify this file but to create a new file where we implement a class that uses that design.
For example, suppose you have used the MainWindow template in the design.ui file, then convert it to Ui_Design.py like to the following structure:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
[...]
def retranslateUi(self, MainWindow):
[...]
Then we will create a new file that we will call logic.py where we will create the file that handles the logic and that uses the previous design:
class Logic(QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
So even if you modify the design and generate the file again .py you will not have to modify the file of the logic.
To generalize the idea we must have the following rules but for this the logic class must have the following structure:
class Logic(PyQtClass, DesignClass):
def __init__(self, *args, **kwargs):
PyQtClass.__init__(self, *args, **kwargs)
self.setupUi(self)
PyQtClass: This class depends on the design chosen.
Template PyQtClass
─────────────────────────────────────────────
Main Window QMainWindow
Widget QWidget
Dialog with Buttons Bottom QDialog
Dialog with Buttons Right QDialog
Dialog with Without Buttons QDialog
DesignClass: The name of the class that appears in your design.
The advantage of this implementation is that you can implement all the logic since it is a widget, for example we will implement the solution closing pyqt messageBox with closeevent of the parent window :
class Logic(QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
def closeEvent(self, event):
answer = QtWidgets.QMessageBox.question(
self,
'Are you sure you want to quit ?',
'Task is in progress !',
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if answer == QtWidgets.QMessageBox.Yes:
event.accept()
else:
event.ignore()
The easiest way is to use the *.ui file directly in the python code, you don't need convert to *.py file every time you change the ui.
you can use this pseudo code in your project.
# imports
from PyQt5 import uic
# load ui file
baseUIClass, baseUIWidget = uic.loadUiType("MainGui.ui")
# use loaded ui file in the logic class
class Logic(baseUIWidget, baseUIClass):
def __init__(self, parent=None):
super(Logic, self).__init__(parent)
self.setupUi(self)
.
.
.
.
def main():
app = QtWidgets.QApplication(sys.argv)
ui = Logic(None)
ui.showMaximized()
sys.exit(app.exec_())
I'm using Qt Designer for design GUI to use in python, after designing my desired UI in Qt Designer, convert it to python code and then I changed generated code to do some action in my python code, but if I changed the UI with Qt Designer and convert it to python code again, I lost my previous changes on my code.
how can I solve the problem?
can we Spreading a Class Over Multiple Files in python to write code in other files?
To avoid having these problems it is advisable not to modify this file but to create a new file where we implement a class that uses that design.
For example, suppose you have used the MainWindow template in the design.ui file, then convert it to Ui_Design.py like to the following structure:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
[...]
def retranslateUi(self, MainWindow):
[...]
Then we will create a new file that we will call logic.py where we will create the file that handles the logic and that uses the previous design:
class Logic(QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
So even if you modify the design and generate the file again .py you will not have to modify the file of the logic.
To generalize the idea we must have the following rules but for this the logic class must have the following structure:
class Logic(PyQtClass, DesignClass):
def __init__(self, *args, **kwargs):
PyQtClass.__init__(self, *args, **kwargs)
self.setupUi(self)
PyQtClass: This class depends on the design chosen.
Template PyQtClass
─────────────────────────────────────────────
Main Window QMainWindow
Widget QWidget
Dialog with Buttons Bottom QDialog
Dialog with Buttons Right QDialog
Dialog with Without Buttons QDialog
DesignClass: The name of the class that appears in your design.
The advantage of this implementation is that you can implement all the logic since it is a widget, for example we will implement the solution closing pyqt messageBox with closeevent of the parent window :
class Logic(QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
def closeEvent(self, event):
answer = QtWidgets.QMessageBox.question(
self,
'Are you sure you want to quit ?',
'Task is in progress !',
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if answer == QtWidgets.QMessageBox.Yes:
event.accept()
else:
event.ignore()
The easiest way is to use the *.ui file directly in the python code, you don't need convert to *.py file every time you change the ui.
you can use this pseudo code in your project.
# imports
from PyQt5 import uic
# load ui file
baseUIClass, baseUIWidget = uic.loadUiType("MainGui.ui")
# use loaded ui file in the logic class
class Logic(baseUIWidget, baseUIClass):
def __init__(self, parent=None):
super(Logic, self).__init__(parent)
self.setupUi(self)
.
.
.
.
def main():
app = QtWidgets.QApplication(sys.argv)
ui = Logic(None)
ui.showMaximized()
sys.exit(app.exec_())
I am using PyQt5 and Qt-Designer to design an application.
How do I instantiate a class for each page on QstackedWidget. I can do it in a single class, all widgets belong to the same QMainWindow. But, the issue is that the file will get too long and impracticale. How do I assign a class for each page. For example, class I handles all the widgets on Page I and class II handles all the widgets on Page II; in the QMainWindow file I can just assign an Object that represents each page.
How can I do it?
Just create multiple modules:
widget1.py
from PyQt5.QtWidgets import QWidget
class Widget1(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
widget2.py
from PyQt5.QtWidgets import QWidget
class Widget2(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
main.py
from widget1 import Widget1
from widget2 import Widget2
from PyQt5.QtWidgets import QMainWindow, QApplication
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setTitle("Stackked widget demo")
self.stacked = QStackedWidget(self)
self.setCentralWidget(self.stacked)
self.widget1 = Widget1()
self.stacked.addWidget(self.widget1)
self.widget2 = Widget2()
self.stacked.addWidget(self.widget2)
if __name__ == "__main__":
app = QApplication([])
mainwin = MainWindow()
mainwin.show()
app.exec_()
I have a QStyledItemDelegate for a table. In one cell I have a QComboBox created through the delegate's createEditor. I add some items to the combobox listing via self.addItem("an item"); however, when I go into the table and actually select the items I have added, they get replaced with index values starting from 0.
How can I have the QComboBox display the actual text I added in addItem instead of the index they're getting stored in?
Here is a small standalone example of my problem:
import sys
from PySide import QtCore, QtGui, QtSql
class EditDelegate(QtGui.QStyledItemDelegate):
def __init__(self, parent=None):
super(EditDelegate, self).__init__(parent)
def createEditor(self, parent, option, index):
editor = TheEditor(parent)
return editor
class TheEditor(QtGui.QComboBox):
def __init__(self, parent=None):
super(TheEditor, self).__init__(parent)
self.addItem("Item 1")
self.addItem("Item 2")
self.addItem("Item 3")
self.setEditable(True)
class TheTable(QtGui.QTableWidget):
def __init__(self, columns, parent=None):
super(TheTable, self).__init__(parent)
self.setItemDelegate(EditDelegate())
self.setEditTriggers(QtGui.QAbstractItemView.AllEditTriggers)
self.setColumnCount(1)
self.setRowCount(1)
self.setHorizontalHeaderLabels(["QCombo"])
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setCentralWidget(TheTable(self))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
frame = MainWindow()
frame.show()
app.exec_()
Updating PySide to the latest version resolves the issue.
It seems that the default combobox delegate is messing up with the data it receives.You could have fixed that with a custom delegate to paint the correct data. But since you have already solved it, Congratulations!.