【问题标题】:Displaying image below menubar in PyQt在 PyQt 的菜单栏下方显示图像
【发布时间】:2019-06-19 12:51:32
【问题描述】:

我有一个简单的流程:用户单击一个按钮,出现一个 QDialog 弹出窗口,我希望在 MenuBar 下方呈现一个菜单栏和一个图像(呈现发生在 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_())

这是迄今为止我所拥有的可重现示例(编辑图像路径),但是图像的一部分出现在菜单栏后面。我该如何解决这个问题?我认为主要问题在于 rect() 调用,因为它似乎正在使用整个窗口,但我希望菜单栏会在“窗口外”。

【问题讨论】:

    标签: python python-3.x pyqt pyqt5 qmenubar


    【解决方案1】:

    一种可能的解决方案是提供一个类似于S.Nick 指示的偏移量,但正如您首先看到的缺点是计算取决于样式和操作系统的偏移量。所以另一种可能的解决方案是创建另一个显示图像的小部件并将其添加到布局中:

    # ...
    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)
    # ...
    

    【讨论】:

    • 这是我尝试做的,但由于某种原因它不会自行调整大小,适用于 sizeHint。谢谢。
    • 我刚刚尝试使用更大的图片,但它似乎仍然根据工具栏的大小将高度挤压了一个偏移量。
    • @Kristijan 你有什么尺寸的图片?如果您可以共享图像以分析问题所在,从而改进我的解决方案,那就太好了
    • 我试过的图片是 892 x 852 px - 如果需要我可以发给你
    • @Kristijan 您还可以分享您的窗口截图以更好地了解您的问题
    【解决方案2】:

    试试看:

    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_())
    

    【讨论】:

    • 好吧,这是显而易见的解决方案,但这意味着 rect() 现在移动了固定数量 - 可能有一种方法可以使菜单栏不属于 rect()。一个潜在的问题是我还必须移动鼠标位置的坐标,假设我要抓住它,因为菜单栏在那里,它不会给出正确的位置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-16
    • 1970-01-01
    • 1970-01-01
    • 2016-05-09
    • 2021-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多