PyQt - Do not want modeless dialog always on top - python

I have a main window that creates modeless dialogs. That's working well, but the dialogs are always in front of the main window. Even if I go back to the main window and use it to give it focus, the dialogs always remain on top. I cannot slide the main window on top of the dialogs.
I'm passing the main window's self as the parent to the dialog.
#In my main window
self.beacon_dlg = dialog_beacon.BeaconDialog(self)
#In the dialog class
class BeaconDialog(QDialog, ui_dialog_beacon.Ui_Dlg_beacon_soh):
def __init__(self, parent):
super(BeaconDialog, self).__init__(parent)
self.setupUi(self)
Any idea how to allow the main window to be in front of the dialogs, and still close the dialog when the main window is closed (parent control)?
(I'm using PyQt 4.10 and Python 2.7 on Windows)
Thanks.

I ended up using the following and it seems to work, but not sure if it's the best method. Instead of using:
def __init__(self, parent):
super(BeaconDialog, self).__init__(parent)
I used:
def __init__(self, parent):
super(BeaconDialog, self).__init__()
thus not making the dialog a child of the main window. (I still passed the main window as an argument to the class for other reasons)
However then in order to have the dialog shutdown correctly I had to overload the main window's closeEvent() and shut down the dialog myself with:
def closeEvnet(self):
if (self.beacon_dlg) : self.beacon_dlg.reject()

From QDialog Class Reference: "A dialog is always a top-level widget, but if it has a parent, its default location is centered on top of the parent's top-level widget (if it is not top-level itself). It will also share the parent's taskbar entry."
You could try to use QWidget instead.

Related

Binding closing of toplevel window

How can I create a binding in tkinter for when someone closes a toplevel window or if it is closed with toplevel1.destroy() or something similar. I am trying to make a small pop-up and when the user closes the main window or toplevel I want to prompt the user to save a file. I have figured out that I can set the actual close button to the function but cannot figure out how to get .destroy() and the closing of the main window to call the function. What should I do to bind the destroy function or window closing function?
Tested code:
import tkinter as tk
class TestWidget(tk.toplevel):
def __init__(self, *args, **kwargs):
tk.Toplevel.__init__(*args, **kwargs)
self.protocol("WM_DELETE_WINDOW", self.close)
def close(self):
print("Closed")
self.destroy()
if __name__ == "__main__":
root = tk.Tk()
TestWidget()
root.mainloop()
So I figured out that if you make a toplevel widget integrated into a class that you can find all the classes with the code below:
for child in root.winfo_children():
print(child)
This returns all the widgets and classes used:
.!testwidget
.!testwidget2
With this I can set up a function in the main window to call the child's close function one by one and this allows me to gain access to all the needed pieces

How to create Dialog without buttons window in PyQt5

Basically I have created a Dialog without buttons window as an alert box using Qt5 designer and compiled to Python using Pyuic5 which resulted into partial code as below:
class Ui_alertwindow(object):
def setupUi(self, alertwindow):
alertwindow.setObjectName("alertwindow")
alertwindow.resize(400, 300)
alertwindow.setStyleSheet("background:#222;")
# much more code
Later on, I will have to modify parts of this window which I could not using Qt5 designer, hence I created a separate class to make the changes, as below:
class alertWindowCustom(QDialog, Ui_alertwindow):
def __init__(self):
QDialog.__init__(self)
self.setupUi(self)
self.run()
def run(self):
print("Changes will be made here")
And then finally call this function in QMainWindow when a button is pressed:
def CreateAlertWindow(self):
alertWindow = alertWindowCustom()
alertWindowInput = alertWindow.exec_()
This creates a white dialog box while not responding and in the console I am getting below errors:
Changes will be made here
Unknown property justification
Unknown property justification
QBasicTimer::stop: Failed. Possibly trying to stop from a different thread
QBasicTimer::stop: Failed. Possibly trying to stop from a different thread
Can anyone tell me what is wrong here?

How to ceate child Modal window in Python tkinter?

Python version is 3.7.
Tried to use tkinter.TopLevel(), the second window is created behind the main window.
I need a true child window which is also modal: can't do anything on the main window before the child is closed.
tkinter.messagebox is very similar but I need my own customized window.
Thank you.
Use the Toplevel widget to set a parent modal dialog
class topDialog:
def __init__(self, parent):
top = self.top = Toplevel(parent)
Label(top, text="Text").pack()
Then follow that up with all of your widgets and such.

How to create Multiple / cascading windows PyQt4?

I want to create 2 windows the upper one needs to be a new project window and the lower one is the project GUI, I have created my lower window completely now I am planning to create a the upper window. How do I create my Upper(New project window)? Can I do it by including a function in my class and calling my function from my run()? or should I create a new class? I am completely confused help me!
My Lower Window(Main Project Code) Code:
class Softw(QtGui.QMainWindow, Doftw.Ui_MainWindow):
def __init__(self, parent=None):
super(Softw, self).__init__(parent)
self.setGeometry(50, 50, 700, 565)
self.setWindowTitle("Softy Softw")
-------------------------
--------(some Functions in Code)
And then finally my run() function which creates and calls the class
def run():
app=QtGui.QApplication(sys.argv)
GUI = Softw()
GUI.show()
sys.exit(app.exec_())
run()
If I do a new function in my class the window shows the upper window first then disappears and then shows the lower window:
def newProject(self):
window = QtGui.QWidget()
window.setGeometry(700,330,500,300)
window.setWindowTitle("New Project")
window.show()
I think the mistake is when to call the function when do I add my function call in this senario? In init method? or Somewhere else?
Thanks!
You can create QWidget using Qt Designer to every window that you want and then you can add them as a class to your file:
For example consider, you have created the .ui file for one window you want to create then convert it to .py using pyuic4 and then create your class like:
from Ui_created import the UI_class
class NewProject(QtGui.QMainWindow, Ui_class):
def __init__(self, parent = None):
super(NewProject, self).__init__(parent)
self.setupUi(self)
Now you can connect this to some button in the main class

Closing a QWidget opened from a QMainWindow

I need to show a QWidget, which code is written in another module, when a certain button is pressed. To accomplish this, I wrote this code:
class Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
#A lot of stuff in here
#The button is connected to the method called Serial_connection
self.connect(self.btn_selection_tool3, SIGNAL("clicked()"), self.Serial_connection)
def Serial_connection(self):
LiveData.LiveData(self).show()
Doing this, I open a QWidget and it works fine. But, when I want to close this QWidget, I can not do it. This is the code of the QWidget:
class LiveData(QWidget):
def __init__(self,parent = None):
super(QWidget, self).__init__(parent)
#Another stuff in here
#I create a "close" button connected to another method
self.connect(self.closeBtn, QtCore.SIGNAL("clicked()"), self.StopAndClose)
def StopAndClose(self):
print "Closing window"
self.close() #HERE IS WHERE I HAVE THE PROBLEM
I´ve tried several options like: self.close(), self.accept() or even sys.exit(1). The problem with the latter sys.exit(1) is that it closes the QWidget and the QMainWindow. So, how can I close this QWidget only? Hope you can help me.
You probably want your QWidget to be a QDialog. If it's a temporary modal widget, you should be calling the dialog like this
dialog = LiveData.LiveData(self)
dialog.exec_()
If you just want to show the dialog at the same time as your main window, and users are meant to interact with both (though from a design perspective, this doesn't sound like a great idea), you can continue to use .show()
Also, you should use the new-style signal/slot syntax. The old syntax hasn't been used for many years.
self.closeButton.clicked.connect(self.StopAndClose)
Though, for a QDialog you can just do
self.closeButton.clicked.connect(self.accept)

Categories

Resources