碰到一个需要将numpy数组(图片)显示在pyqt5的窗口中,上网查到的一般显示出来图片周围会有大片的空白。以下代码是将qt5的窗口适应到图片。
# !/usr/bin/env python
# -*- utf-8 -*-
import matplotlib
matplotlib.use("Qt5Agg")
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
# from PyQt5 import QtCore
from PyQt5.QtWidgets import QWidget, QSizePolicy
import numpy as np
class PltCanvas(FigureCanvas):
def __init__(self, parent = None, width = 320, height = 240, dpi = 100):
figure = Figure(figsize=(width, height), dpi=dpi)
figure.set_tight_layout({'pad':0, 'w_pad': 0, 'h_pad': 0})
figure.set_constrained_layout_pads(w_pad=0, h_pad=0, wspace=0, hspace=0)
self.subplot = figure.add_subplot(111)
self.compute_initial_figure()
FigureCanvas.__init__(self, figure)
self.setParent(parent)
FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
self.subplot.imshow = self._imshow(self.subplot.imshow)
img = np.zeros([height, width])
self.subplot.imshow(img)
def _imshow(self, func):
def wraper(img, **kargs):
self.subplot.clear()
if not kargs.has_key('aspect'):
kargs['aspect'] = 'auto'
img = func(img, **kargs)
self.subplot.set_axis_off()
self.subplot.set_xticks([])
self.subplot.set_yticks([])
return img
return wraper
def compute_initial_figure(self):
pass
class FloatingWindow(QWidget):
def __init__(self):
super(FloatingWindow, self).__init__(None, Qt.FramelessWindowHint)
self._padding = 5
self.initTitleLabel()
#self.setWindowTitle = self._setTitleText(self.setWindowTitle)
self.setWindowTitle("Floating Window")
self.initLayout()
#self.setMinimumWidth(250)
self.setMouseTracking(True)
self.initDrag()
def initDrag(self):
self._move_drag = False
self._corner_drag = False
self._bottom_drag = False
self._right_drag = False
def initTitleLabel(self):
self._title_lable = QLabel(self)
self._title_lable.setMouseTracking(True)
self._title_lable.setIndent(10)
self._title_lable.move(0, 0)
def initLayout(self):
self._main_layout = QVBoxLayout()
self._main_layout.setSpacing(0)
self._main_layout.addWidget(QLabel(), Qt.AlignLeft)
self._main_layout.addStretch()
self.setLayout(self._main_layout)
self._canvas = canvas.PltCanvas(self)
self._main_layout.addWidget(self._canvas)
self._main_layout.setContentsMargins(0, 0, 0, 0)
def addLayout(self, layout):
self._main_layout.addLayout(layout)
def _setTitleText(self, func):
def wrapper(*args):
self._title_lable.setText(*args)
return func(*args)
return wrapper
def setTitleAlignment(self, align):
self._title_lable.setAlignment(align | Qt.AlignVCenter)
def setCloseButton(self, flag):
if flag == True:
self._close_btn = QPushButton(b'\xef\x81\xb2'.decode('utf-8'), self)
#self._close_btn.setObjectName('CloseButton')
#self._close_btn.setToolTip('close window')
self._close_btn.setMouseTracking(True)
self._close_btn.setFixedHeight(self._title_lable.height())
self._close_btn.clicked.connect(self.close)
def setMinMaxButton(self, flag):
if flag == True:
self._min_btn = QPushButton(b'\xef\x80\xb0'.decode('utf-8'), self)
#self._min_btn.setObjectName("MinMaxButton")
#self._min_btn.setToolTip("minimize")
self._min_btn.setMouseTracking(True)
self._min_btn.setFixedHeight(self._title_lable.height())
self._min_btn.clicked.connect(self.showMinimized)
self._max_btn = QPushButton(b'\xef\x80\xb1'.decode('utf-8'), self)
self._max_btn.setObjectName("MinMaxButton")
self._max_btn.setToolTip("maximize")
self._max_btn.setMouseTracking(True)
#self._max_btn.setFixedHeight(self._title_lable.height())
self._max_btn.clicked.connect(self._changeNormalButton)
def _changeNormalButton(self):
try:
self.showMaximized()
self._max_btn.setText(b'\xef\x80\xb2'.decode('utf-8'))
self._max_btn.setToolTip("resume")
self._max_btn.disconnect()
self._max_btn.clicked.connect(self._changeMaxButton)
except:
pass
def resizeEvent(self, QResizeEvent):
#self._title_lable.setFixedWidth(self.width())
try:
self._close_btn.move(self.width() - self._close_btn.width(), 0)
except:
pass
try:
self._min_btn.move(self.width() - (self._close_btn.width() + 1) * 3 + 1, 0)
except:
pass
try:
self._max_btn.move(self.width() - (self._close_btn.width() + 1) * 2 + 1, 0)
except:
pass
self._right_rect = [QPoint(self.width() - self._padding, 1),
QPoint(self.width() + 1, self.height() + 1)]
self._bottom_rect = [QPoint(1, self.height() - self._padding),
QPoint(self.width(), self.height() + 1)]
self._corner_rect = [QPoint(self.width() - self._padding, self.height() - self._padding),
QPoint(self.width() + 1, self.height() + 1)]
def _pointInArea(self, p, area):
return (p.x() > area[0].x()) and (p.x() < area[1].x()) and (p.y() > area[0].y()) and (p.y() < area[1].y())
def mousePressEvent(self, event):
if event.button() != Qt.LeftButton:
return
if self._pointInArea(event.pos(), self._corner_rect):
self._corner_drag = True
event.accept()
elif self._pointInArea(event.pos(), self._right_rect):
self._right_drag = True
event.accept()
elif self._pointInArea(event.pos(), self._bottom_rect):
self._bottom_drag = True
elif event.pos().y() < self._title_lable.height():
self._move_drag = True
self._move_drag_pos = event.globalPos() - self.pos()
event.accept()
def mouseMoveEvent(self, event):
if self._pointInArea(event.pos(), self._corner_rect):
self.setCursor(Qt.SizeFDiagCursor)
elif self._pointInArea(event.pos(), self._bottom_rect):
self.setCursor(Qt.SizeVerCursor)
elif self._pointInArea(event.pos(), self._right_rect):
self.setCursor(Qt.SizeHorCursor)
else:
self.setCursor(Qt.ArrowCursor)
if self._right_drag:
self.resize(event.pos().x(), self.height())
event.accept()
elif self._bottom_drag:
self.resize(self.width(), event.pos().y())
event.accept()
elif self._corner_drag:
self.resize(event.pos().x(), event.pos().y())
event.accept()
elif self._move_drag:
self.move(event.globalPos() - self._move_drag_pos)
event.accept()
def mouseReleaseEvent(self, event):
self._move_drag = False
self._corner_drag = False
self._bottom_drag = False
self._right_drag = False
if __name__ == '__main__':
from PyQt5.QtWidgets import QApplication
import sys
app = QApplication(sys.argv)
win = FloatingWindow()
win.setCloseButton(True)
win.setMinMaxButton(True)
win.show()
sys.exit(app.exec_())
代码参考了:
https://www.cnblogs.com/hhh5460/p/4322652.html
http://www.cnblogs.com/senyang/p/9132652.html
https://www.cnblogs.com/sthinker/p/6775683.html
https://blog.csdn.net/qq_38528972/article/details/78573591