I have Qdialog with that I open from main window:
Dialog = myDialog(self)
Here is the code from new opened Dialog:
class myDialog(QtGui.QDialog, Ui_DialogCalibration):
def __init__(self, parent=None):
super(myDialog, self).__init__(parent)
self.setupUi(self)
How can pass parameter(lint) from main window to this new window, something like
Dialog = myDialog(self, listInformation)
and then in myDialog class use that list
class myDialog(QtGui.QDialog, Ui_DialogCalibration):
def __init__(self, parent=None, listInfo):
super(myDialog, self).__init__(parent)
self.listInfo = listInfo
self.setupUi(self)
Then, when you go to create the myDialog, you can add the list as a parameter. When you need to use it inside of your myDialog, you would access it as self.listInfo.
EDIT: To further expand on the comments:
If you have def __init__(self, parent=None, listInfo=None), you would call it as Dialog = myDialog(parent=self, listInfo=listInfo). If you had it as def __init__(self, parent, listInfo) you would do Dialog = myDialog(self, listInfo). Hopefully you see the pattern here.
Related
I am trying to open a new window inside a mdiArea and I achieved it with the following code.
class Window(QMainWindow, MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.pushButton.clicked.connect(self.open_tool)
def open_tool(self):
# Create Sub Window
new_win = new_Window()
self.mdiArea.addSubWindow(new_win)
new_win.show()
self.mdiArea.cascadeSubWindows()
Now, since each new window that I open, has multiple long tasks, I wanted to run each new window in a new thread in order to prevent freezing of the entire gui.
I tried using the following code:
class Tool_Thread(QtCore.QThread):
def __init__(self, mdiArea):
# Get Widget Area
super().__init__()
self.mdiArea = mdiArea
# Create Sub Window
self.new_win = new_Window()
self.mdiArea.addSubWindow(self.new_win)
def run(self):
self.new_win.show()
and running it in the main gui with
class Window(QMainWindow, MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.pushButton.clicked.connect(self.open_tool)
def open_tool(self):
new_tool = TMTC_Thread(self.mdiArea)
new_tool .start()
but the main gui continues to freeze. Is there any way to handle cases like this?
I have a parent and child window. When you push the button from the parent class the child is shown and the parent is hidden. Is there anyway to keep the taskbar icon visible when doing this?
from PyQt5.QtCore import Qt, QDateTime
from PyQt5.QtWidgets import *
from PyQt5 import QtGui
class ParentWindow(QDialog):
def __init__(self):
super(ParentWindow, self).__init__()
self.cw = None
self.button = QPushButton('Go to child')
self.button.clicked.connect(self.child)
layout = QHBoxLayout()
layout.addWidget(self.button)
self.setLayout(layout)
self.show()
def child(self):
self.cw = ChildWindow(self)
self.hide()
def parent(self):
self.cw.close()
self.show()
class ChildWindow(QDialog):
def __init__(self, parent):
super(ChildWindow, self).__init__(parent)
self.button = QPushButton('Go to parent')
self.button.clicked.connect(self.parent().parent)
layout = QHBoxLayout()
layout.addWidget(self.button)
self.setLayout(layout)
self.show()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = ParentWindow()
sys.exit(app.exec_())
The problem is that a child QDialog "shares" the same taskbar entry as its parent, and when the parent is hidden, so does the taskbar entry, no matter if a child is visible.
A possible solution is to not hide the parent, but minimize it. Keep in mind that this has only been tested as working on Windows, on Linux you can have unexpected behavior (depending on how the window manager relates to modal windows) and I don't know how it will work out on MacOs.
The idea is to use showMinimized() on the parent, then show the child, activate it to make it visible on top and, most importantly, use exec_() to ensure it has full control and make it behave as a dialog should.
Then we connect both the accepted and rejected signals of the dialog to restore the main window, and connect the clicked signal to accept.
class ParentWindow(QDialog):
def __init__(self):
super(ParentWindow, self).__init__()
self.cw = None
self.button = QPushButton('Go to child')
self.button.clicked.connect(self.child)
layout = QHBoxLayout()
layout.addWidget(self.button)
self.setLayout(layout)
self.show()
def child(self):
self.cw = ChildWindow(self)
self.showMinimized()
self.cw.show()
self.cw.activateWindow()
self.cw.exec_()
class ChildWindow(QDialog):
def __init__(self, parent):
super(ChildWindow, self).__init__(parent)
self.button = QPushButton('Go to parent')
self.button.clicked.connect(self.accept)
layout = QHBoxLayout()
layout.addWidget(self.button)
self.setLayout(layout)
self.accepted.connect(self.parent().showNormal)
self.rejected.connect(self.parent().showNormal)
PS: I ended up not using a custom function to call back the parent at all, but remember that you shouldn't overwrite function/property names like parent.
Below is an example of a custom delegated QComboBox. When I make a selection, click out (or otherwise lose focus with the QComboBox), and then TAB back in (gain focus), I lose my original selection. For example, using the below code if I choose "Item 2", click out, then TAB back in, the selection will go back to "Item 1."
How can I maintain the selection?
I am assuming this issue occurs because I am using addItem() in TheEditor QComboBox class every time it is initialized except I am not too sure how I should be approaching this method. Should I instead be initalizing TheEditor in the EditDelegate __ init __ class so that it is only initialized once and not every time it is focused? How might I do that properly?
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_()
Note: PySide v1.2.0
As QT Introduction to (Model/View Programming) says
Note that we do not need to keep a pointer to the editor widget because the view takes responsibility for destroying it when it is no longer needed.
editor is temporary object. But you can try catching selection from old editor and pass it to new editor like this:
class EditDelegate(QtGui.QStyledItemDelegate):
editorsLastIndex=None
def __init__(self, parent=None):
super(EditDelegate, self).__init__(parent)
def createEditor(self, parent, option, index):
editor = TheEditor(parent)
if self.editorsLastIndex != None:
editor.setCurrentIndex(self.editorsLastIndex)
editor.currentIndexChanged.connect(self.editorIndexChanged)
return editor
def editorIndexChanged(self, index):
self.editorsLastIndex = index
I have done a GUI interface with Qt designer and compiled the .ui file into a .py file. In main window I have this class:
class Projektdlg(QMainWindow, ui_Projekt.Ui_MainWindow):
def __init__(self, parent=None):
super(Projektdlg, self).__init__(parent)
self.setupUi(self)
self.connect(self.actionCalibration, SIGNAL("triggered()"), self.CalibrationSettings)
I want to open the QDialog from the generated ui_calibration file when clicking on calibration from the tool bar. How to do that?
def CalibrationSettings(self):
Dialog = ui_calibration.Ui_DialogCalibration()
All modules are imported
Try something like this:
class myDialog(QtGui.QDialog, Ui_DialogCalibration):
def __init__(self, parent=None):
super(myDialog, self).__init__(parent)
self.setupUi(self)
Then in your class:
Dialog = myDialog(self)
Then you can call Dialog.show() or Dialog.exec_()
I'm creating an app using Eric4 and PyQt4.
I have two dialog boxes, one runs as a thread and the other is a standard dialog box with a label inside, which I want to change to an image.
Every time the main window thread runs I want it to change the current image displayed in the dialog box to a new image. Everything works fine except every time the thread runs it creates a new dialog box with the new image inside - I want it to change the image in the dialog box that's currently open.
Dialog box with image inside:
class SubWindow(QDialog, Ui_subWindow):
def __init__(self, parent = None):
QDialog.__init__(self, parent)
self.setupUi(self)
self.show()
def main(self, img):
pic = self.imgView
pic.setPixmap(QtGui.QPixmap(os.getcwd() + img))
Thread which changes the image:
class MainWindow(QDialog, Ui_MainWindow, threading.Thread):
def __init__(self, parent = None):
threading.Thread.__init__(self)
QDialog.__init__(self, parent)
self.setupUi(self)
self.show()
#some code here which does some stuff then calls changeImg()
def changeImg(self):
img = SubWindow()
img.main(img)
I've not included all my code, only the relevant bits.
It looks like the problem is that you are creating a new SubWindow every time you wish to change the image. I would recommend creating the SubWindow as an attribute to MainWindow in the MainWindiw.__init__ function:
class MainWindow(QDialog, Ui_MainWindow, threading.Thread):
def __init__(self, parent = None):
threading.Thread.__init__(self)
QDialog.__init__(self, parent)
self.setupUi(self)
self.show()
self.img = SubWindow() # Create SubWindow once here
def changeImg(self):
self.img.main(self.img) # Only change the image, no new SubWindow