I have my main application QWindow where, when I press a QPushButton a new child window (a QWidget) pops up. There are two ways of exiting the QWidget window:
Click the X in the top right hand corner, or
Click on the 'Finished' QPushButton I have in the QWidget window.
I would like to ensure that, when either method is used to exit the window, the QWidget is deleted. I believe that I can ensure this in the second case by adding self.deleteLater() to the function called when the 'Finished QPushButton is clicked, but I am struggling to see how to do this in the first case.
You can set an attribute on the widget to do this:
class Widget(QtGui.QWidget)
def __init__(self, parent=None)
super(Widget, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
Your "Finished" button then only has to call self.close() (which is equivalent to clicking the titlebar close button).
Related
How to propagate the parent's click event in Pyside2 as if I have clicked the button directly while hovering over it?
This is a very peculiar problem, and I haven't been able to find even a question like this.
A button is positioned on the main UI window. When clicked, it hides the parent window, and spawns another window at that position. I need it to work with a single click, for example, I want to press the button, and not release the mouse immediately, but hover over a certain part of the newly spawned window and then release it.
This works perfectly fine if I click the button directly , but the problem is I need to click the button from the main UI window.
I am doing it by sending "mousePressEvent" from the main UI window to the child widget's "mousePressEvent", like this:
def mousePressEvent(self, event): #parent mouse press event
#----
#----
self.FocusedButton.mousePressEvent(event) # child widget
When I activate the button from the mainUI window, the window is immediately hidden and the new window is spawned. However, since I haven't performed mouse release yet, I am stuck into the parent's mouse press event loop. The mouse doesn't invoke paint event and doesn't register mouseMoveEvent until I release the click because the mainUI window is hidden and mouse tracking doesn't work any more.
I have tried setting the flags of the window in every way, (QtCore.Qt.WA_TransparentForMouseEvents,True ) for example, but none of it worked.
The main UI window inherits from "QtWidgets.QWidget" and does not have the clicked method.
consider the following code:
from tkinter import *
root=Tk()
root.geometry('700x700')
frame=Frame(root)
frame.pack(fill=BOTH,expand=True)
def opencanvas():
canvas=Canvas(frame,bg='red')
canvas.place(x=50,y=50,height=300,width=300)
button2=Button(frame,text='exit',command=canvas.place_forget)
button2.place(x=5,y=10)
button1=Button(frame,text='open',command=opencanvas)
button1.place(x=5,y=10)
mainloop()
this program opens a frame in a tkinter window and a 'open' button in the frame.when pressing 'open',a canvas opens and a button named 'exit' appears in frame at the same place of the open button.exit button hides canvas.
when clicking the 'exit' button,i want to disappear the 'exit' button automatically after performing its operation(ie,hiding canvas). what should i do to work this?
I want to insert some commands inside opencanvas() which disappears the button2 right after it pressed.
nb: the two buttons should place at same place and have same dimensions.
Use button1.place_forget() or .grid_forget() or .pack_forget() depending on which geometry manager you use. If you use these, then the button is hidden. To get the button back use .place() etc...
If you want to, you could use button1.destroy() but this deletes the button permanently, and if you have to make that button again, you have to initialise from start.
Use button.place_forget() for your code to hide the button and then, button1.place(x=5,y=10) to show your button
I found the answer for my question.It can be done by using lambda inside button command as follows.
button2=Button(frame,text='exit',command=lambda:[canvas.place_forget(),button2.place_forget()])
lambda function executes the commands one by one.
I know that similar question was already answered, but my case is a little bit different
Case:
I have a QWidget which contains a QLineEdit and a QListWidget
The QListWidget is a FramelessWindow which means that it is not located in the main window but it appears independently (actually it is a dynamically changing list depending on the content of the QLineEdit filed: "filter as you type")
Problems:
When I close the main window, it will not close the QListWidget automatically. After the main window closed, the QListWidget will be still seen. - I could not find event, in the QWidget, which would work for that purpose. The closeEvent(self, event) is never triggered.
When I move the main window the QListWidget will be still stay in the original position. It will not follow the QLineEdit's position. I could not find event, in the QWidget, which would work for that purpose.
Conditions:
I do not want to detect the changes in the main window. I know that the
closeEvent(self, event)
works in the main window, and I could delegate it to the QListWidget.
BUT I want to write an independent widget, which does not depend on the setting in the main window.
Can somebody help me with telling/suggesting how to detect the window close/window move inside a widget?
If you need the code (pretty long ~300 lines), I can copy it here.
I am using PyQt5 and Python3 to write a program.
I am using QGraphicsBlurEffect to make a blur effect on the main widget when a pop up windows is shown.
The problem is that when the popup window is closed the blur effect is still on the main widget and it doesn't show as normal. How can I set it to normal after closing the popup window?(I set the graphicsEffect of mainwindow to None in closing event of popup window but it doesn't change anything).
This is the code:
main widget:
self.blureffect = QGraphicsBlurEffect(self) #defining the effect
def fontpgshow(self): #shows the popup window
self.setGraphicsEffect(self.blureffect) #puts the blur effect on the main widget
#the 3 bottom lines show the popup window
import fontwindow
self.fontpg = fontwindow.fontpage()
self.fontpg.show()
popup window:
def closeEvent(self,event):
event.accept()
#in the bottom lines I set the effect of main window to None
import settingswindow
self.setpg = settingswindow.settingspage()
self.setpg.setGraphicsEffect(None)
I solved my problem by changing the type of the pop up window from QWidget to QDialog and I used self.accept() and self.reject() in the QDialog for sending signals back to the main widget that here it was the setting page. After getting signal I set the graphics effect of the main widget to None and everything is working ok now.
I have run into a problem durring abaqus programming with phyton 2.7.
I'm using Tkinter and making a window with a lot of controls on it.
My main problem is that durring my plugin window is opened, the user needs to click on abaqus menuitems, browse modells, etc. So using the main program while my plugin still works on screen.
If I do create my Tk window without thread, than when the user clicks on abaqus main windo functions while my plugin is opened, then abaqus will not respond or crash with "LoadlibraryA error 193"
(example: while plugin runs and user clicks on Viewvport menĂ¼/ViewPort Annotation Options then he/she wont be able to change tabs)
If i do create my Tk window inside a thread, then the al the Tk window controls will only responds the mouse events after I leave the Tk window with my cursor.
(example: I make 2 notebook page and after start i click on the not selected one. then nothing happens until my mous inside the Tk window, but as soon as i move it out, the click takes effect and the tab changes...)
The threaded version of my code:
import threading
class pilotDB(threading.Thread):
def shutdown_ttk_repeat(self):
self.root.eval('::ttk::CancelRepeat')
self.root.destroy()
def __init__(self):
import threading
threading.Thread.__init__(self)
def refresh(self):
self.root.after(50, self.refresh)
def tabpage(self):
import ttk
import sys
self.notebook = ttk.Notebook(self.root)
self.tabpage_tab1 = ttk.Frame(self.notebook,width=400,height=500)
self.tabpage_tab2 = ttk.Frame(self.notebook,width=400,height=500)
self.notebook.add(self.tabpage_tab1, text='Tab1')
self.notebook.add(self.tabpage_tab2, text='Tab2')
self.notebook.place(x=30, y=40)
def run(self):
import Tkinter
self.root = Tkinter.Tk()
self.root.protocol("WM_DELETE_WINDOW", self.shutdown_ttk_repeat)
self.tabpage()
self.root.after(1000, self.refresh())
self.root.mainloop()
app = pilotDB()
app.start()
app/pilotDB has no function named "start" (last line of the code posted). If I put a call to self.run() in init, and delete threading, then the program works as expected, i.e. opens a window and displays 2 tabs and the user can switch between tabs, all the time the mouse is in the window as is normal. Note also that the refresh() function does nothing but call itself repeatedly. You should try to find the offending code by first commenting the lines for the "WM_DELETE_WINDOW", shutdown_ttk_repeat and the call to execute the function tabpage() which leaves a basic window. Then uncomment one and run it, and repeat until you find the error.