如何将 Matplotlib 图添加到我的 pyqt 布局
How to add Matplotlib graph to my pyqt layout
目前,我正在开发一个使用 PYQT 组合框选择应用程序的应用程序。组合框中的选择有:
- 文本框(只允许用户输入)
- 图片(让用户拖放图片查看图片)
- 音频(让用户拖放音频文件以查看频谱
从 matplotlib 绘制的图表)- 只能使用 wav 文件。
除了音频部分,一切正常。当我拖放我的 wav 文件时,会发生这种情况。
我明白为什么它被推低了。因为上面有布局。所以我的问题是如何将其放入“lastWidget”布局?这样它就可以以与我的文本框和图像相同的布局显示。我尝试将它添加到另一个变量并添加一个小部件,还尝试添加像素图。但是,我似乎无法让它工作。
import sys, os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
#audio plot on pyqt
import numpy as np
import matplotlib.pyplot as plt
from scipy.io.wavfile import read
from matplotlib.backends.backend_qt5agg import *
from matplotlib.figure import Figure
class UI(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Programme")
self.setFixedSize(600, 600)
central = QWidget()
self.setCentralWidget(central)
self.layout = QVBoxLayout(central)
combo = QComboBox(self)
combo.addItems(("textbox", "image", "audio"))
combo.setFixedSize(200, 30)
self.layout.addWidget(combo)
self.lastWidget = QLineEdit(self)
self.layout.addWidget(self.lastWidget)
self.lastWidget.setFixedSize(500, 500)
combo.activated[str].connect(self.onChanged)
self.show()
def onChanged(self, text):
if text == 'textbox':
self.layout.removeWidget(self.lastWidget)
self.lastWidget.deleteLater()
self.lastWidget = QLineEdit()
self.lastWidget.setFixedSize(500, 500)
elif text == 'image':
self.layout.removeWidget(self.lastWidget)
self.lastWidget.deleteLater()
#Doing drag and drop for image
self.lastWidget = DragAndDropImage()
self.layout.addWidget(self.lastWidget)
elif text == 'audio':
self.layout.removeWidget(self.lastWidget)
self.lastWidget.deleteLater()
#Doing drag and drop for Audio
self.lastWidget = DragAndDropAudio()
self.layout.addWidget(self.lastWidget)
self.layout.addWidget(self.lastWidget)
QApplication.processEvents()
self.adjustSize()
class DragAndDropAudio(QLabel):
def __init__(self):
super().__init__()
self.setAcceptDrops(True)
self.setFixedSize(500, 500)
def dragEnterEvent(self, event):
event.accept()
def dragMoveEvent(self, event):
event.accept()
def dropEvent(self, event):
if event.mimeData().hasUrls:
file_path = event.mimeData().urls()[0].toLocalFile()
# print(file_path)
self.set_audio(file_path)
event.accept()
else:
event.ignore()
def set_audio(self, file_path):
canvas = FigureCanvas(Figure(figsize=(5, 4)))
ax = canvas.figure.subplots()
# fig, self.ax = plt.subplots(figsize=(5, 4), dpi=120)
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
# read audio samples
input_data = read(file_path)
audio = input_data[1]
# plot the first 1024 samples
ax.plot(audio[0:1024])
# label the axes
ax.plot(t, s)
ax.set(xlabel='time (s)', ylabel='Amlitude',
title='Audio Spectrum')
ex.layout.addWidget(canvas)
class DragAndDropImage(QLabel):
def __init__(self):
super().__init__()
self.setAcceptDrops(True)
self.setFixedSize(500, 500)
self.setAlignment(Qt.AlignCenter)
self.setText('\n\n Drop Image Here (InputImage) \n\n')
self.setStyleSheet('''
QLabel{
border: 4px dashed #aaa
}
''')
def setPixmap(self, image):
super().setPixmap(image)
def dragEnterEvent(self, event):
if event.mimeData().hasImage:
event.accept()
else:
event.ignore()
def dragMoveEvent(self, event):
if event.mimeData().hasImage:
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if event.mimeData().hasImage:
event.setDropAction(Qt.CopyAction)
file_path = event.mimeData().urls()[0].toLocalFile()
self.set_image(file_path)
event.accept()
else:
event.ignore()
def set_image(self, file_path):
ex.lastWidget.setPixmap(QPixmap(file_path))
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = UI()
sys.exit(app.exec_())
不要添加和删除小部件,在这种情况下最好使用 QStackedWidget。
class UI(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Programme")
self.setFixedSize(600, 600)
central = QWidget()
self.setCentralWidget(central)
self.combo = QComboBox()
self.combo.setFixedSize(200, 30)
self.textbox = QLineEdit()
self.textbox.setFixedSize(500, 500)
self.dnd_image = DragAndDropImage()
self.dnd_audio = DragAndDropAudio()
self.stacked_widget = QStackedWidget()
self.stacked_widget.addWidget(self.textbox)
self.stacked_widget.addWidget(self.dnd_image)
self.stacked_widget.addWidget(self.dnd_audio)
layout = QVBoxLayout(central)
layout.addWidget(self.combo)
layout.addWidget(self.stacked_widget)
self.combo.addItem("textbox", self.textbox)
self.combo.addItem("image", self.dnd_image)
self.combo.addItem("audio", self.dnd_audio)
self.combo.currentIndexChanged.connect(self.onChanged)
self.show()
def onChanged(self):
widget = self.combo.currentData()
if isinstance(widget, QWidget):
self.stacked_widget.setCurrentWidget(widget)
self.adjustSize()
目前,我正在开发一个使用 PYQT 组合框选择应用程序的应用程序。组合框中的选择有:
- 文本框(只允许用户输入)
- 图片(让用户拖放图片查看图片)
- 音频(让用户拖放音频文件以查看频谱 从 matplotlib 绘制的图表)- 只能使用 wav 文件。
除了音频部分,一切正常。当我拖放我的 wav 文件时,会发生这种情况。
我明白为什么它被推低了。因为上面有布局。所以我的问题是如何将其放入“lastWidget”布局?这样它就可以以与我的文本框和图像相同的布局显示。我尝试将它添加到另一个变量并添加一个小部件,还尝试添加像素图。但是,我似乎无法让它工作。
import sys, os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
#audio plot on pyqt
import numpy as np
import matplotlib.pyplot as plt
from scipy.io.wavfile import read
from matplotlib.backends.backend_qt5agg import *
from matplotlib.figure import Figure
class UI(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Programme")
self.setFixedSize(600, 600)
central = QWidget()
self.setCentralWidget(central)
self.layout = QVBoxLayout(central)
combo = QComboBox(self)
combo.addItems(("textbox", "image", "audio"))
combo.setFixedSize(200, 30)
self.layout.addWidget(combo)
self.lastWidget = QLineEdit(self)
self.layout.addWidget(self.lastWidget)
self.lastWidget.setFixedSize(500, 500)
combo.activated[str].connect(self.onChanged)
self.show()
def onChanged(self, text):
if text == 'textbox':
self.layout.removeWidget(self.lastWidget)
self.lastWidget.deleteLater()
self.lastWidget = QLineEdit()
self.lastWidget.setFixedSize(500, 500)
elif text == 'image':
self.layout.removeWidget(self.lastWidget)
self.lastWidget.deleteLater()
#Doing drag and drop for image
self.lastWidget = DragAndDropImage()
self.layout.addWidget(self.lastWidget)
elif text == 'audio':
self.layout.removeWidget(self.lastWidget)
self.lastWidget.deleteLater()
#Doing drag and drop for Audio
self.lastWidget = DragAndDropAudio()
self.layout.addWidget(self.lastWidget)
self.layout.addWidget(self.lastWidget)
QApplication.processEvents()
self.adjustSize()
class DragAndDropAudio(QLabel):
def __init__(self):
super().__init__()
self.setAcceptDrops(True)
self.setFixedSize(500, 500)
def dragEnterEvent(self, event):
event.accept()
def dragMoveEvent(self, event):
event.accept()
def dropEvent(self, event):
if event.mimeData().hasUrls:
file_path = event.mimeData().urls()[0].toLocalFile()
# print(file_path)
self.set_audio(file_path)
event.accept()
else:
event.ignore()
def set_audio(self, file_path):
canvas = FigureCanvas(Figure(figsize=(5, 4)))
ax = canvas.figure.subplots()
# fig, self.ax = plt.subplots(figsize=(5, 4), dpi=120)
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
# read audio samples
input_data = read(file_path)
audio = input_data[1]
# plot the first 1024 samples
ax.plot(audio[0:1024])
# label the axes
ax.plot(t, s)
ax.set(xlabel='time (s)', ylabel='Amlitude',
title='Audio Spectrum')
ex.layout.addWidget(canvas)
class DragAndDropImage(QLabel):
def __init__(self):
super().__init__()
self.setAcceptDrops(True)
self.setFixedSize(500, 500)
self.setAlignment(Qt.AlignCenter)
self.setText('\n\n Drop Image Here (InputImage) \n\n')
self.setStyleSheet('''
QLabel{
border: 4px dashed #aaa
}
''')
def setPixmap(self, image):
super().setPixmap(image)
def dragEnterEvent(self, event):
if event.mimeData().hasImage:
event.accept()
else:
event.ignore()
def dragMoveEvent(self, event):
if event.mimeData().hasImage:
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if event.mimeData().hasImage:
event.setDropAction(Qt.CopyAction)
file_path = event.mimeData().urls()[0].toLocalFile()
self.set_image(file_path)
event.accept()
else:
event.ignore()
def set_image(self, file_path):
ex.lastWidget.setPixmap(QPixmap(file_path))
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = UI()
sys.exit(app.exec_())
不要添加和删除小部件,在这种情况下最好使用 QStackedWidget。
class UI(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Programme")
self.setFixedSize(600, 600)
central = QWidget()
self.setCentralWidget(central)
self.combo = QComboBox()
self.combo.setFixedSize(200, 30)
self.textbox = QLineEdit()
self.textbox.setFixedSize(500, 500)
self.dnd_image = DragAndDropImage()
self.dnd_audio = DragAndDropAudio()
self.stacked_widget = QStackedWidget()
self.stacked_widget.addWidget(self.textbox)
self.stacked_widget.addWidget(self.dnd_image)
self.stacked_widget.addWidget(self.dnd_audio)
layout = QVBoxLayout(central)
layout.addWidget(self.combo)
layout.addWidget(self.stacked_widget)
self.combo.addItem("textbox", self.textbox)
self.combo.addItem("image", self.dnd_image)
self.combo.addItem("audio", self.dnd_audio)
self.combo.currentIndexChanged.connect(self.onChanged)
self.show()
def onChanged(self):
widget = self.combo.currentData()
if isinstance(widget, QWidget):
self.stacked_widget.setCurrentWidget(widget)
self.adjustSize()