Reputation: 195
I have a simple flow: user clicks a button, a QDialog popup appears and I wish to render a MenuBar and an image below the MenuBar (the rendering happens during the paintEvent).
import sys
from PyQt5 import QtGui
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QDialog, QMenuBar, QAction, QHBoxLayout
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.button = QPushButton()
self.button.setText("Click")
self.button.setMaximumHeight(100)
self.button.setMaximumWidth(100)
self.button.clicked.connect(self.clicked)
self.layout().addWidget(self.button)
self.show()
def clicked(self):
self.something = SecondExample()
self.something.exec()
class SecondExample(QDialog):
def __init__(self):
super().__init__()
self.installEventFilter(self)
layout = QHBoxLayout()
toolbar = QMenuBar()
toolbar.addAction(QAction("Edit", toolbar))
toolbar.addAction(QAction("Polygon", toolbar))
toolbar.addAction(QAction("Rectangle", toolbar))
layout.setMenuBar(toolbar)
self.setLayout(layout)
self.pixmap = QPixmap(r"C:\Users\kjankosk\Desktop\Panasonic-OLED-TV-FZ950-Lifestyle.jpg")
self.resize(self.pixmap.width(), self.pixmap.height())
def paintEvent(self, event):
super().paintEvent(event)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
painter.drawPixmap(self.rect(), self.pixmap)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
Here is a reproducible example of what I have so far (edit the image path), however part of the image appears behind the menu bar. How can I fix this issue? I think the main problem is with the rect() call as it seems to be using the whole window, but I was hoping that the menu bar would be "outside the window".
Upvotes: 2
Views: 918
Reputation: 243973
A possible solution is to give an offset like the one indicated by S.Nick but as you saw a disadvantage first is to calculate the offset that is dependent on the style and OS. So another possible solution is to create another widget where the image is displayed and add it to the layout:
# ...
class Widget(QWidget):
def __init__(self):
super().__init__()
self.pixmap = QPixmap(
r"C:\Users\kjankosk\Desktop\Panasonic-OLED-TV-FZ950-Lifestyle.jpg"
)
def paintEvent(self, event):
super().paintEvent(event)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
painter.drawPixmap(self.rect(), self.pixmap)
def sizeHint(self):
return self.pixmap.size()
class SecondExample(QDialog):
def __init__(self):
super().__init__()
layout = QHBoxLayout(self)
toolbar = QMenuBar()
toolbar.addAction(QAction("Edit", toolbar))
toolbar.addAction(QAction("Polygon", toolbar))
toolbar.addAction(QAction("Rectangle", toolbar))
layout.setMenuBar(toolbar)
widget = Widget()
layout.addWidget(widget)
# ...
Upvotes: 2
Reputation: 13651
Try it:
import sys
from PyQt5 import QtGui
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (QMainWindow, QApplication, QPushButton, QDialog,
QMenuBar, QAction, QHBoxLayout, QWidget, QGridLayout)
class SecondExample(QDialog):
def __init__(self):
super().__init__()
self.installEventFilter(self)
toolbar = QMenuBar()
toolbar.addAction(QAction("Edit", toolbar))
toolbar.addAction(QAction("Polygon", toolbar))
toolbar.addAction(QAction("Rectangle", toolbar))
layout = QHBoxLayout()
layout.setMenuBar(toolbar)
self.setLayout(layout)
self.pixmap = QPixmap("D:/_Qt/__Qt/img/max1.jpg") # py-qt.png
self.resize(self.pixmap.width(), self.pixmap.height())
def paintEvent(self, event):
super().paintEvent(event)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
# painter.drawPixmap(self.rect(), self.pixmap)
rect = self.rect().x(), self.rect().y()+20, self.rect().width(), self.rect().height()-20 # +++
painter.drawPixmap(*rect, self.pixmap) # +++
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.button = QPushButton(self)
self.button.setText("Click")
self.button.setMaximumHeight(100)
self.button.setMaximumWidth(100)
self.button.clicked.connect(self.clicked)
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
layout = QGridLayout(centralWidget)
# self.layout().addWidget(self.button)
layout.addWidget(self.button)
def clicked(self):
self.something = SecondExample()
self.something.show() # exec()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
Upvotes: 0