I have a QMainWindow
that I initialize with a QWidget
. I want that each Time I'll press the button New
In my QMainWiindow
, it will open the QWidget
temporarily (in my case, until mouse button release).
I'm having trouble interacting QMainWindow
with the QWidget
. I tried many options, but it seemed like everything I tried tied the QWidget
to the QMainWindow
screen, and I don't want that.
It will be easier with an example:
TempWidgetMenu.py
is my QMainWindow
class. When I press New
, a QWidget
will appear, it Will color the screen gray-ish, and will color a rectangle from a button press, to the button release (like in windows snipping tool).
I Want that that every time I press on New
, I'll be able to draw a rectangle from every point of the screen, and so it does the first time.
When I press New
for the second time (or afterwards), it will color everything but the main menu screen, and will not respond to the button actions.
I want the widget to be the "parent" of the program in the screen every time I press the button.
TempWidgetMenu.py (main):
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QAction
from PyQt5.QtGui import QPixmap, QPainter
import TempWidget
class Menu(QMainWindow):
def __init__(self):
super().__init__()
newAct = QAction('New', self)
newAct.triggered.connect(self.new_image_window)
self.toolbar = self.addToolBar('Exit')
self.toolbar.addAction(newAct)
self.opac_rect = TempWidget.TempOpacWidget()
self.image = QPixmap("background.png")
self.setGeometry(100, 100, 500, 300)
self.resize(self.image.width(), self.image.height())
self.show()
def new_image_window(self):
self.opac_rect.start()
def paintEvent(self, event):
painter = QPainter(self)
painter.drawPixmap(self.rect(), self.image)
if __name__ == '__main__':
app = QApplication(sys.argv)
mainMenu = Menu()
sys.exit(app.exec_())
TempWidget.py :
import tkinter as tk
from PyQt5 import QtWidgets, QtCore, QtGui
class TempOpacWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
root = tk.Tk()
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
self.setGeometry(0, 0, screen_width, screen_height)
self.setWindowTitle(' ')
self.begin = QtCore.QPoint()
self.end = QtCore.QPoint()
self.busy = False
def start(self):
self.busy = True
self.setWindowOpacity(0.3)
self.show()
def paintEvent(self, event):
if self.busy:
brush_color = (128, 128, 255, 100)
opacity = 0.3
else:
brush_color = (0, 0, 0, 0)
opacity = 0
self.setWindowOpacity(opacity)
qp = QtGui.QPainter(self)
qp.setBrush(QtGui.QColor(*brush_color))
qp.drawRect(QtCore.QRectF(self.begin, self.end))
def mousePressEvent(self, event):
self.begin = event.pos()
self.end = self.begin
self.update()
def mouseMoveEvent(self, event):
self.end = event.pos()
self.update()
def mouseReleaseEvent(self, event):
self.busy = False
self.repaint()
I realize I'm initializing the TempOpacWidget
once at the start. I want to initialize it only once, because it is doing the same thing.
How can I fix it, such that the TempOpacWidget
will be the parent every time I call him?
Edit: If something is not clear, run the code it will make perfect sense. Press New
, Choose a rectangle (with mouse), and then press New
again to choose another rectangle, and you will understand what is the problem.
If I understand you correctly, you want
Menu.opac_rect
to open in a separate window while your mouse button is pressed. I see a couple of issues with this. First, if you want aQWidget
to open in a separate window, you should pass aQt.windowFlags
argument to theQWidget
constructor, i.e.Don't forget to import the
QtCore
namespace.Secondly,
QAction
doesn't have the signals you need. Only objects that inherit fromQWidget
will havemousePressEvent
andmouseReleaseEvent
. If you must keep things in the toolbar,QToolBar
hasQToolBar.addWidget
, so you could use aQLabel
instead ofQAction
, and overwrite the necessary event handlers.You'll probably have to fiddle with the
QLabel
styling to make it look right, but I think this will accomplish what you are looking for.I do not quite understand what's going to happen, but I added and changed some lines of code. Click the
New
button and draw a rectangle. You should have new ideas. Good luck.TempWidgetMenu.py
TempWidget.py