How to reference currently open dialog box? - python

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

Related

How to fix PyQgis layout resizing problem when making window bigger?

I'm working on creating python plugin that implements image viewer and use layout to plased elements in correct plases. I want to resize all elements in dialog window of this plugin using resizeEvent of QDialog, but I have one strange problem: when I want to make dialog window smaller - all works good like on image1, but, if I want to make window bigger I have seen a problem like on image2:
Here is my resizeEvent method for my dialog:
def resizeEvent(self, a0: QResizeEvent):
geom = list(self.geometry().getCoords())
x_shift = geom[2] - geom[0] #transform x coord from monitor coords to dialog window coords
y_shift = geom[3] - geom[1] #transform y coord from monitor coords to dialog window coords
self.verticalLayout.setGeometry(QRect(0, 0, x_shift, y_shift))
And here is my code how I connect my ui with python code using uic:
import os
from qgis.PyQt import uic
from qgis.PyQt import QtWidgets
FORM_CLASS, _ = uic.loadUiType(os.path.join(
os.path.dirname(__file__), 'name_of_ui'))
class nameDialog(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, parent=None):
super(status_checkerDialog, self).__init__(parent)
self.setupUi(self)
In this script, I create the resize function. Also, I would like to add that I use to build the skeleton of the module named Plugin Builder. Maybe this information will help you point out exactly where I am making a mistake. I also add the code skeleton that implements all functions of the module:
class status_checker:
def __init__(self, iface):
"Constructor"
def add_action(
self,
icon_path,
text,
callback,
enabled_flag=True,
add_to_menu=True,
add_to_toolbar=True,
status_tip=None,
whats_this=None,
parent=None):
"""Add a toolbar icon to the toolbar"""
def initGui(self):
"""Create the menu entries and toolbar icons inside the QGIS GUI"""
def unload(self):
"""Removes the plugin menu item and icon from QGIS GUI."""
def run(self):
"""Run method that performs all the real work"""
# Create the dialog with elements (after translation) and keep reference
# Only create GUI ONCE in callback, so that it will only load when the plugin is started
if self.first_start == True:
self.first_start = False #self.first_start is a variable that is created in the initialization function and initially set to true
self.dlg = status_checkerDialog()

PyQt mdiArea New Window in Thread

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?

Setting button signals for widget created via wrapper function

I am trying to create a GUI (see attached screenshot) where it has about 6 sets of widgets where each set comprises of QLabel, QLineEdit and QPushButton.
Instead of writing the widgets and the layout again and again, I thought of writing up a wrapper function such that I will only need to write up 6 lines for the creation.
However, while this works efficiently for me in terms of the widgets creation, I realized that I am not able to set the Signal for the button(s) as I do not know the widget's names.
What will be the best way to set the signals if I decided to use this wrapper methodology?
The following is a screenshot of what I am trying to achieve as well as my code:
class MyDevTool(QtGui.QWidget):
def __init__(self, parent=None):
super(MyDevTool, self).__init__(parent)
self._create_ui()
def _create_hbox_layout(self, label):
h_layout = QtGui.QHBoxLayout()
label = QtGui.QLabel(label)
label.setFixedWidth(80)
line_edit = QtGui.QLineEdit()
push_btn = QtGui.QPushButton("<<<")
h_layout.addWidget(label)
h_layout.addWidget(line_edit)
h_layout.addWidget(push_btn)
return h_layout
def _create_ui(self):
main_layout = QtGui.QVBoxLayout()
main_layout.addLayout(
self._create_hbox_layout("Input Directory")
)
main_layout.addLayout(
self._create_hbox_layout("Output Directory")
)
self.setLayout(main_layout)

pyqt popup window not displaying properly

I have created two different pyqt windows, and within one of them, by pressing a button, it should bring up another smaller window. While my code does pretty much exactly what I just dais it should do, there is a problem with the way the smaller popup window is displayed.
This is my code for displaying the windows and the button functionality:
from PyQt4 import QtGui
from EnterprisePassport import Ui_StudentEnterprisePassport
from Session_tracker import Ui_Session_tracker
class StudentEnterprisePassport(Ui_StudentEnterprisePassport):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setupUi(self)
self.sessionTracker_btn.clicked.connect(self.handleButton)
self.window2 = None
def handleButton(self):
if self.window2 is None:
self.window2 = Session_tracker(self)
self.window2.show()
class Session_tracker(Ui_Session_tracker):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setupUi(self)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = StudentEnterprisePassport()
window.show()
sys.exit(app.exec_())
I can still use the functions within the window, but I can't move it, or close it, and there is no title bar. Have I done something wrong within my code for the popup window to appear like this?
Edit:
Original Session tracker window: Original window
Popup session tracker window: Popup window
In order to show the other widget in it's own window, it has to be a QMainWindow or a QDialog.
One option, if you don't want to convert your existing Session_tracker to a QDialog, is to just wrap it in a QDialog
def handleButton(self):
if self.window2 is None:
self.window2 = QtGui.QDialog(self)
lay = QtGui.QVBoxLayout()
self.window2.setLayout(lay)
self.session_tracker = Session_tracker(self.window2)
lay.addWidget(self.session_tracker)
self.window2.show()

Passing parameter from main window to pop-up Qdialog window

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.

Categories

Resources