Main form and child form - python

I am quite new in pyqt design
and I have a question.
I have a Main form. and a child form.
I want the child form to be opened inside the parent form.
how can I do that in python?
I have written a code that just open the form.
but it didnot open it inside the form?
Thanks
##this method creates an Form Main
class FrmMainForm (QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.uiMain = FrmMain.Ui_MainWindow()
self.uiMain.setupUi(self)
action = self.uiMain.menuManual_Mode.addAction(self.tr('ManualMode'))
action.triggered.connect(self.handleNewWindow)
def handleNewWindow(self):
ex = Main(self.uiMain)
ex.show()
class Main(QtGui.QWidget):
white = "QWidget { background-color:#FFFFFF }"
red = "QWidget { background-color:#AB0000}"
green = "QWidget { background-color:#00C000}"
def __init__(self,p):
QtGui.QWidget.__init__(self)
self.p = p
self.initLogAnalyzerManuall()
def initLogAnalyzerManuall(self):
QtGui.QWidget.__init__(self)
self.ui = Ui_Form()
self.ui.setupUi(self,self.p)

The child window will be garbage-collected when the handleNewWindow method returns, and so it will never get the chance to be shown.
You need to keep a reference to the child window, but the way you go about it depends on what you are trying to achieve. Do you literally want a new window to be opened every time the button is clicked? If so, then do this:
def handleNewWindow(self):
ex = Main(self)
ex.show()
class Main(QtGui.QWidget):
...
def __init__(self, parent):
QtGui.QWidget.__init__(self, parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.ui = Ui_Form()
self.ui.setupUi(self)
On the other hand, if you want the same child window to be opened every time, then do this:
class FrmMainForm (QtGui.QWidget):
def __init__(self):
...
self._child_window = None
def handleNewWindow(self):
if self._child_window is None:
self._child_window = Main(self)
self._child_window.show()
class Main(QtGui.QWidget):
...
def __init__(self, parent):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
Note that in both cases, you can access the main window from the child window with self.parent().

Related

Trouble with PyQt4 List Widget

So my problem is the following:
I have a program that I created in QT Designer and added some code in Python.
There is an main window and two windows wich appear when you click an button in the window before.
The List Widget is in the second window:
Hope with this picture you can understand what I mean
So now I want to add some Items to my list widget.
def add_number_to_list(self):
self.ui.list_of_numbers.addItem('test')
So I call this function on another place but it didn't happen anything.
If I add an print command, to test if the function works: The print is showed. But nothing appears in the list widget...
What is wrong?
import sys
from PyQt4 import QtGui
import p_design, p_edit_numbers, p_add_number
number_to_add = ''
class Example(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = p_design.Ui_MainWindow()
self.ui.setupUi(self)
self.ui.manually_alarm.clicked.connect(self.alarm)
self.ui.edit_numbers.clicked.connect(self.open_edit_numbers)
def alarm(t1,t2):
#send sms to numbers
print('ALARM!')
def open_edit_numbers(self):
self.test = EditNumbers(self)
self.test.show()
class EditNumbers(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = p_edit_numbers.Ui_MainWindow()
self.ui.setupUi(self)
self.ui.add_number.clicked.connect(self.open_add_number)
### Problem! ###
def add_number_to_list(self):
self.ui.list_of_numbers.addItems('test')
################
def open_add_number(self):
self.t3 = AddNumber(self)
self.t3.show()
class AddNumber(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = p_add_number.Ui_MainWindow()
self.ui.setupUi(self)
self.ui.add.clicked.connect(self.add_number)
def add_number(self):
global number_to_add
editnumbers=EditNumbers()
editnumbers.add_number_to_list()
def main():
app = QtGui.QApplication(sys.argv)
form = Example()
form.show()
sys.exit(app.exec_())
main()

How to find out if second window is closed

I have an application that uses another application from someone else halfway through (both applications use .ui files). Therefore I create the second application in SecondWindow and hide MainWindow. Now I would like to show MainWindow again after SecondWindow is closed. I found the solution in the answer works, but now the background of SecondWindow is wrong because it uses the background of MainWindow. Is there a way to find out if SecondWindow is closed in the class from MainWindow without making MainWindow a parent of SecondWindow or to prevent the background changes caused by the parenthood?
My current code looks somewhat like this:
## Define main window class from template
path = os.path.dirname(os.path.abspath(__file__))
uiFile = os.path.join(path, 'test.ui')
Ui_MainWindow, QtBaseClass = uic.loadUiType(uiFile)
uiFile2 = os.path.join(path, 'monitor.ui')
WindowTemplate, SecondWindowClass = pg.Qt.loadUiType(uiFile2)
class SecondWindow(SecondWindowClass):
def closeThis(self):
self.close()
self.parent().show()
def __init__(self, parent):
super(SecondWindow, self).__init__(parent)
# ensure this window gets garbage-collected when closed
self.setWindowTitle('pyqtgraph example: Qt Designer')
self.ui = WindowTemplate()
self.ui.setupUi(self)
self.show()
class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def showSecond(self):
self.second.show()
self.hide()
def __init__(self):
QtGui.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.ui=uic.loadUi(uiFile, self)
self.setupUi(self)
self.show()
self.second = SecondWindow(self)
self.second.hide()
self.ui.end_button.clicked.connect(lambda x:self.showSecond())
win = MainWindow()
if __name__ == '__main__':
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
It's not actually necessary for the second window to be a child of the first.
So you should be able to do something like this:
class SecondWindow(SecondWindowClass):
def closeThis(self):
self.close()
self.first.show()
def __init__(self, first):
super(SecondWindow, self).__init__()
self.first = first
...
class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def showSecond(self):
self.second.show()
self.hide()
def __init__(self):
...
self.second = SecondWindow(self)
self.second.hide()

PyQt: How to add new tabs to QTextEdit?

I need to add a new tab, but I am having problems. I want to add new tabs in the main window, and keep the methods of the class Editor(). I can do this without having to create the class Editor() but need it to be so. Sorry for my English.
This is my code:
from PyQt4 import QtGui
from PyQt4 import QtCore
class Main(QtGui.QMainWindow):
def __init__(self):
super(Main, self).__init__()
self.initUi()
def initUi(self):
self.setWindowTitle("Editor")
self.resize(640, 480)
self.edit = Editor()
newAc = QtGui.QAction('New', self)
newAc.setShortcut('Ctrl+N')
newAc.triggered.connect(self.new_)
menu = self.menuBar()
filemenu = menu.addMenu('&File')
filemenu.addAction(newAc)
self.tab = QtGui.QTabWidget(self)
self.setCentralWidget(self.tab)
class Editor(QtGui.QTextEdit):
def __init__(self, parent=None):
super(Editor, self).__init__(parent)
def new_(self):
tab = QtGui.QTextEdit(self.tab)
self.tab.addTab(tab, 'Untitled')
def main():
import sys
app = QtGui.QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
If you want to have the same text on both (or more) tabs you can use the same Editor class, but if not, you need instantiate an Editor object for each tab.
Also your code have some problems:
1- You are handling the tabs inside Editor objects. Instead, you must handle tabs at Main level.
2- The "default" tab you're adding when you create the Main object do not have any related QTextEdit change:
self.tab = QtGui.QTabWidget(self)
self.setCentralWidget(self.tab) # <---- tab without QTextEdit
add this:
self.tab = QtGui.QTabWidget(self)
self.editor = Editor(self.tab) # editor receives self.tab widget as parent.
self.setCentralWidget(self.tab)
also you will need define Editor class before Main.
3- Main object don't have any method called new_, Editor does. So the line:
newAc.triggered.connect(self.new_)
it's wrong.
So your code might look like:
from PyQt4 import QtGui
from PyQt4 import QtCore
class Editor(QtGui.QTextEdit):
def __init__(self, parent=None):
super(Editor, self).__init__(parent)
class Main(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.initUi()
def initUi(self):
self.setWindowTitle("Editor")
self.resize(640, 480)
newAc = QtGui.QAction('New', self)
newAc.setShortcut('Ctrl+N')
newAc.triggered.connect(self.new_)
menu = self.menuBar()
filemenu = menu.addMenu('&File')
filemenu.addAction(newAc)
self.tab = QtGui.QTabWidget(self)
self.setCentralWidget(self.tab)
self.tab.addTab(Editor(), "New Text")
def new_(self):
self.tab.addTab(Editor(), "New text")
def main():
import sys
app = QtGui.QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

how to get subclassed QWidgets from QToolBox?

I wrote a few customized widget classes by subclassing QWidget. I created a few customized widgets using them and added them to a QToolBox.
class BaseWidget(QtGui.QWidget):
def __init__(self, parent=None):
# initialize
def mymethod():
pass
class AWidget(BaseWidget):
def __init__(self, parent=None):
# initialize
def mymethod():
print "A"
class BWidget(BaseWidget):
def __init__(self, parent=None):
# initialize
def mymethod():
print "B"
Now I want to loop over all the widgets added to the QToolBox and call a method of these customized widgets:
class toolboxWidget(QtGui.QToolBox):
def __init__(self, parent=None):
super(toolboxWidget, self).__init__(parent=parent)
a = AWidget(self)
b = BWidget(self)
self.addItem(a, "A")
self.addItem(b, "B")
def printMethod(self):
for i in range(self.count()):
self.widget(i).mymethod()
However, since widget() method of QToolBox only returns objects of QWidget type, when calling printMethod() of toolboxWidget object, it gives the following error:
AttributeError: 'QWidget' object has no attribute 'mymethod'.
Is there a way I can convert the QWidget returned by widget() to BaseWidget objects? Thanks.
After fixing all the obvious errors and omissions in your example code, I was able to get it working without any problems.
If the QToolBox.widget method didn't return an instance of one of your BaseWidget subclasses, it would be a bug in PyQt (or sip).
Here is a script that works for me using sip 4.15.4 and PyQt 4.10.3:
from PyQt4 import QtCore, QtGui
class BaseWidget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
def mymethod(self):
pass
class AWidget(BaseWidget):
def __init__(self, parent=None):
BaseWidget.__init__(self, parent)
def mymethod(self):
print "A"
class BWidget(BaseWidget):
def __init__(self, parent=None):
BaseWidget.__init__(self, parent)
def mymethod(self):
print "B"
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.toolbox = QtGui.QToolBox(self)
a = AWidget(self.toolbox)
b = BWidget(self.toolbox)
self.toolbox.addItem(a, "A")
self.toolbox.addItem(b, "B")
self.button = QtGui.QPushButton('Test', self)
self.button.clicked.connect(self.printMethod)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.toolbox)
layout.addWidget(self.button)
def printMethod(self):
for i in range(self.toolbox.count()):
self.toolbox.widget(i).mymethod()
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 300, 300)
window.show()
sys.exit(app.exec_())

Opening new window from python gui

I have a problem opening new window in my python gui app. I have 3 classes (first login is shown, and than 2 windows are opened). This works fine:
class LoginDialog(QtGui.QDialog):
def __init__(self, parent = None):
super(LoginDialog, self).__init__(parent)
.....
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QWidget.__init__(self, parent)
.....
class ImageViewerMainWindow(QtGui.QMainWindow):
def __init__(self, path, parent = None):
super(ImageViewerMainWindow, self).__init__(parent)
.....
if __name__ == "__main__":
qtApp = QtGui.QApplication(sys.argv)
loginDlg = LoginDialog()
if not loginDlg.exec_():
sys.exit(-1)
MyMainWindow = MainWindow()
MyMainWindow.show()
viewer = ImageViewerMainWindow("C:\image.jpg")
viewer.show()
sys.exit(qtApp.exec_())
I need viewer to be executed from MainWindow but when I put it like this it just flashes and disappear:
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QWidget.__init__(self, parent)
.....
def DoOpenImageViewer(self):
viewer = ImageViewerMainWindow("C:\image.jpg")
viewer.show()
You need to keep a reference to you viewer, otherwise the new window is destroyed when viewer goes out of scope and is garbage collected.
If you only need one Window at a time, you can do something like:
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QWidget.__init__(self, parent)
.....
def DoOpenImageViewer(self):
self.viewer = ImageViewerMainWindow("C:\image.jpg")
self.viewer.show()
Otherwise you could use a list to store the references.

Categories