Python PyQt5-在QMainMenu中,如何使QWidget成为父项(临时)?
我有一个Python PyQt5-在QMainMenu中,如何使QWidget成为父项(临时)?,python,pyqt,pyqt5,qwidget,qmainwindow,Python,Pyqt,Pyqt5,Qwidget,Qmainwindow,我有一个QMainWindow,我用QWidget初始化它。我希望每次在我的QMainWiindow中按下按钮New,它都会临时打开QWidget(在我的情况下,直到松开鼠标按钮) 我与QWidget交互QMainWindow时遇到问题。我尝试了许多选项,但似乎我尝试的所有方法都将QWidget绑定到QMainWindow屏幕上,我不希望这样 举个例子会更容易: TempWidgetMenu.py是我的QMainWindow类。当我按下New时,会出现一个QWidget,它会将屏幕涂成灰色,并将
QMainWindow
,我用QWidget
初始化它。我希望每次在我的QMainWiindow
中按下按钮New
,它都会临时打开QWidget
(在我的情况下,直到松开鼠标按钮)
我与QWidget
交互QMainWindow
时遇到问题。我尝试了许多选项,但似乎我尝试的所有方法都将QWidget
绑定到QMainWindow
屏幕上,我不希望这样
举个例子会更容易:
TempWidgetMenu.py
是我的QMainWindow
类。当我按下New
时,会出现一个QWidget
,它会将屏幕涂成灰色,并将从按下按钮到释放按钮的矩形涂成灰色(就像在windows剪贴工具中一样)
我希望每次按下New
,我都能够从屏幕的每个点绘制一个矩形,第一次也是如此。
当我第二次(或之后)按New
时,它将为除主菜单屏幕外的所有内容着色,并且不会响应按钮操作
我希望每次按下按钮时,小部件都是屏幕上程序的“父级”
TempWidgetMenu.py(主):
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()
我意识到我正在初始化TempOpacWidget
一次。我只想初始化它一次,因为它正在做同样的事情
我如何修复它,使得TempOpacWidget
将是我每次给他打电话时的家长
编辑:如果有不清楚的地方,请运行代码,它将非常有意义。按
New
,选择一个矩形(用鼠标),然后再次按New
选择另一个矩形,您就会明白问题所在。如果我理解正确,您希望在按下鼠标按钮时在单独的窗口中打开菜单。opac\u rect
。我认为这有几个问题。首先,如果希望在单独的窗口中打开QWidget
,则应将Qt.windowFlags
参数传递给QWidget
构造函数,即
self.opac_rect = TempWidget.TempOpacWidget(None, QtCore.Qt.Window)
不要忘记导入QtCore
名称空间
其次,QAction
没有您需要的信号。只有从QWidget
继承的对象才会具有mousePressEvent
和mouseereleaseevent
。如果必须在工具栏中保留内容,QToolBar
具有QToolBar.addWidget
,因此可以使用QLabel
而不是QAction
,并覆盖必要的事件处理程序
self.opac_rect = TempWidget.TempOpacWidget(None, QtCore.Qt.Window)
newAct = QLabel('New')
newAct.mousePressEvent = lambda e: self.opac_rect.start()
newAct.mouseReleaseEvent = lambda e: self.opac_rect.stop() # You'll need to write this
self.toolbar.addWidget(newAct)
您可能需要修改
QLabel
样式以使其看起来正确,但我认为这将实现您所寻找的功能。我不太明白会发生什么,
但我添加并更改了一些代码行。
单击New
按钮并绘制一个矩形。
你应该有新的想法。
祝你好运
TempWidgetMenu.py
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QAction
from PyQt5.QtGui import QPixmap, QPainter
from PyQt5.QtCore import Qt # +++
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) # +++ self
self.imageShow() # +++
def imageShow(self):
self.setWindowFlags(Qt.WindowStaysOnTopHint) # +++
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)
# +++
def closeEvent(self, event):
self.opac_rect.close()
event.accept()
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
from PyQt5.QtCore import Qt # +++
class TempOpacWidget(QtWidgets.QWidget):
# def __init__(self):
# super().__init__()
def __init__(self, parent=None):
super(TempOpacWidget, self).__init__() # no (parent)
self.parent = parent # +++
print("self=`{}`, \nparent=`{}`".format(self, self.parent))
self.setWindowFlags(Qt.WindowStaysOnTopHint) # +++
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.setWindowFlags(Qt.WindowStaysOnTopHint) # +++
self.busy = True
self.setWindowOpacity(0.5) # 0.3
self.show()
def paintEvent(self, event):
if self.busy:
brush_color = (128, 128, 255, 100)
opacity = 0.5 # 0.3
else:
brush_color = (0, 0, 0, 0)
opacity = 0.5 # 0 <<<---------
# or try `0`, how suits you !? <<<---------
#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.parent.hide()
self.begin = event.pos()
self.end = self.begin
self.update()
def mouseMoveEvent(self, event):
self.end = event.pos()
self.update()
def mouseReleaseEvent(self, event):
print("def mouseReleaseEvent(self, event):---")
self.busy = False
self.repaint()
self.parent.imageShow() # +++
将tkinter作为tk导入
从PyQt5导入QtWidgets、QtCore、QtGui
从PyQt5.QtCore导入Qt#+++
类TempOpacWidget(qtwidget.QWidget):
#定义初始化(自):
#super()。\uuuu init\uuuuu()
def uuu init uuu(self,parent=None):
super(TempOpacWidget,self)。uuu init_uuu()35; no(父级)
self.parent=parent#+++
打印(“self=`{}`,\nPart=`{}`.”格式(self,self.parent))
self.setWindowFlags(Qt.WindowStaysOnTopHint)#+++
root=tk.tk()
screen\u width=root.winfo\u screenwidth()
screen\u height=root.winfo\u screenheight()
self.setGeometry(0,0,屏幕宽度,屏幕高度)
#self.setWindowTitle(“”)
self.begin=QtCore.QPoint()
self.end=QtCore.QPoint()
self.busy=False
def启动(自):
self.setWindowFlags(Qt.WindowStaysOnTopHint)#+++
self.busy=True
self.setWindowOpacity(0.5)#0.3
self.show()
def paintEvent(自身,事件):
如果self.busy:
画笔颜色=(128、128、255、100)
不透明度=0.5#0.3
其他:
画笔颜色=(0,0,0,0)
不透明度=0.5#0不完全相同。当我按下“新建”按钮时,我希望它为整个屏幕上色,只有在释放不同的按钮(与按下“新建”按钮无关)后,屏幕才会恢复正常。我更改了代码示例,如果您运行它,它将更有意义。@TheCrystalShip与新闻发布联系起来,而不是单击,这有多重要?彩色小部件(部分透明)是否覆盖了您正在绘制的图像?这非常重要。我更新了我的代码。按“新建”,选择一个矩形,然后再次按“新建”,您将了解问题所在。
import tkinter as tk
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import Qt # +++
class TempOpacWidget(QtWidgets.QWidget):
# def __init__(self):
# super().__init__()
def __init__(self, parent=None):
super(TempOpacWidget, self).__init__() # no (parent)
self.parent = parent # +++
print("self=`{}`, \nparent=`{}`".format(self, self.parent))
self.setWindowFlags(Qt.WindowStaysOnTopHint) # +++
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.setWindowFlags(Qt.WindowStaysOnTopHint) # +++
self.busy = True
self.setWindowOpacity(0.5) # 0.3
self.show()
def paintEvent(self, event):
if self.busy:
brush_color = (128, 128, 255, 100)
opacity = 0.5 # 0.3
else:
brush_color = (0, 0, 0, 0)
opacity = 0.5 # 0 <<<---------
# or try `0`, how suits you !? <<<---------
#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.parent.hide()
self.begin = event.pos()
self.end = self.begin
self.update()
def mouseMoveEvent(self, event):
self.end = event.pos()
self.update()
def mouseReleaseEvent(self, event):
print("def mouseReleaseEvent(self, event):---")
self.busy = False
self.repaint()
self.parent.imageShow() # +++