我希望我能得到一些幫助來解決我整天被困的問題。我已經查看了以前的問題,但似乎沒有什么與我面臨的問題完全匹配。也許一雙新鮮的眼睛可以引導我走向正確的方向。我將在我的問題末尾包含我的代碼。
背景:
我正在開發一個由主視窗和彈出視窗組成的簡單應用程式。主視窗僅包含一個按鈕,按下時會打開彈出視窗。彈出視窗包含兩個復選框選項,一個確定按鈕和一個取消按鈕。按下時,彈出視窗的確定按鈕會向主視窗回傳一個信號。該信號包含 1 和 0 的串列,具體取決于復選框的狀態。該串列的目的是使主視窗中的函式可以確定要繪制哪些畫布(圖 1、圖 2 或兩者)。
需要注意的是,主視窗是使用網格布局組織的,每個畫布都應顯示在第 3 列的一行中,并在第 4 列中顯示相應的標簽。創建兩個畫布時的預期結果如圖所示:

問題:
一切正常,直到信號回傳到主視窗中 popup_input() 的插槽為止。沒有錯誤發生,但畫布根本沒有出現。從 popup_input() 獲取用于創建圖形的代碼并將其放入 open_options() 似乎確實有效,并給出了如上所示的圖形。但是,我的目標是在用戶做出選擇后顯示這些圖。有誰知道為什么畫布沒有出現?
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import QDialog, QApplication, QMainWindow, QLabel, QPushButton
from PyQt5.QtGui import QFont
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.ticker import FormatStrFormatter
class Options(QMainWindow):
popup_response = QtCore.pyqtSignal(object)
def __init__(self):
super().__init__()
self._title = 'Plotting Options'
self.setWindowTitle(self._title)
self.selected_plots = [1, 1] # Always have both options selected by default
self.option1 = QtWidgets.QCheckBox('Option 1')
self.option1.setChecked(True)
self.option2 = QtWidgets.QCheckBox('Option 2')
self.option2.setChecked(True)
self.checkbox_layout = QtWidgets.QHBoxLayout()
self.checkbox_layout.addWidget(self.option1)
self.checkbox_layout.addWidget(self.option2)
self.ok_button = QtWidgets.QPushButton('OK', self)
self.ok_button.clicked.connect(lambda: self.clicked_ok())
self.cancel_button = QtWidgets.QPushButton('Cancel', self)
self.cancel_button.clicked.connect(lambda: self.clicked_cancel())
self.button_layout = QtWidgets.QHBoxLayout()
self.button_layout.addWidget(self.ok_button)
self.button_layout.addWidget(self.cancel_button)
self._popup = QtWidgets.QWidget()
self.setCentralWidget(self._popup)
self.layout = QtWidgets.QGridLayout(self._popup)
self.layout.addLayout(self.checkbox_layout, 0, 0)
self.layout.addLayout(self.button_layout, 1, 0)
def finalize_selected_plots(self):
if self.option1.isChecked() == False:
self.selected_plots[0] = 0
if self.option2.isChecked() == False:
self.selected_plots[1] = 0
return self.selected_plots
def clicked_ok(self):
self.plots = self.finalize_selected_plots()
# Send selection back to Results Window
main_window = MainWindow()
static_reply = self.plots
self.popup_response.connect(main_window.popup_input)
self.popup_response.emit(static_reply)
self.plots = [1,1]
self.close()
def clicked_cancel(self):
self.close()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.exPopup = Options()
self.data_to_plot = [[1, 5, 10], [2, 4, 6], [6, 4, 2]] # Dummy values
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
self.button_options = QtWidgets.QPushButton('Plot Options', self)
self.button_options.clicked.connect(self.open_options)
self.option_layout = QtWidgets.QHBoxLayout()
self.option_layout.addWidget(self.button_options)
self.layout = QtWidgets.QGridLayout(self._main)
self.layout.addLayout(self.option_layout, 0, 2)
def open_options(self):
self.exPopup.show()
@QtCore.pyqtSlot(object)
def popup_input(self, reply):
plot_title_font_size = 15
data = self.data_to_plot
if reply[0] != 0:
self.figure_xy1 = FigureCanvas(Figure(figsize=(5, 5)))
self._figure1 = self.figure_xy1.figure.subplots()
self._figure1.grid()
self.layout.addWidget(self.figure_xy1, 1, 3)
self.figure_label1 = QLabel('Test Plot 1', self)
self.figure_label1.setFont(QFont('Times', plot_title_font_size))
self.figure_label1.setAlignment(QtCore.Qt.AlignLeft)
self.layout.addWidget(self.figure_label1, 1, 4)
x = data[0]
y = data[1]
self._figure1.plot(x, y, '-')
self._figure1.set_xlabel('x')
self._figure1.set_ylabel('y1')
self._figure1.figure.canvas.draw()
if reply[1] != 0:
self.figure_xy2 = FigureCanvas(Figure(figsize=(5, 5)))
self._figure2 = self.figure_xy2.figure.subplots()
self._figure2.grid()
self.layout.addWidget(self.figure_xy2, 2, 3)
self.figure_label2 = QLabel('Test Plot 2', self)
self.figure_label2.setFont(QFont('Times', plot_title_font_size))
self.figure_label2.setAlignment(QtCore.Qt.AlignLeft)
self.layout.addWidget(self.figure_label2, 2, 4)
x = data[0]
y = data[2]
self._figure2.plot(x, y, '-')
self._figure2.set_xlabel('x')
self._figure2.set_ylabel('y2')
self._figure2.figure.canvas.draw()
if __name__ == '__main__':
app = QApplication(sys.argv)
widget = QtWidgets.QStackedWidget()
main_window = MainWindow()
widget.addWidget(main_window)
widget.setWindowTitle("Main Window")
widget.show()
try:
sys.exit(app.exec_())
except:
print("Exiting")
uj5u.com熱心網友回復:
我找到了解決我的問題的方法。在 Reddit 的 pyqt 頁面上 jmacey 的幫助下,我得出了以下結論:
- 我的彈出視窗應該繼承 QDialog vs QMainWindow
- 利用 QDialogBu??ttonBox 簡化對話框按鈕方案
- 分別包括我的確定和取消按鈕的接受和拒絕信號。我還為 clicked_ok 添加了一個額外的信號,它會在對話框關閉時執行我想要的功能。
- 彈出對話框應該從我的主視窗執行。如果我在對話框中單擊“確定”,它將運行與繪圖相關的代碼。
這是我更新的課程:
class Options(QDialog):
popup_response = QtCore.pyqtSignal(object)
def __init__(self, parent=None):
super().__init__(parent)
self._title = 'Plotting Options'
self.setWindowTitle(self._title)
self.setGeometry(100, 100, 300, 200)
self.selected_plots = [1, 1] # Always have both options selected by default
self.option1 = QtWidgets.QCheckBox('Option 1')
self.option1.setChecked(True)
self.option2 = QtWidgets.QCheckBox('Option 2')
self.option2.setChecked(True)
self.checkbox_layout = QtWidgets.QHBoxLayout()
self.checkbox_layout.addWidget(self.option1)
self.checkbox_layout.addWidget(self.option2)
self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.button_box.accepted.connect(self.clicked_ok)
self.button_box.rejected.connect(self.reject)
self.popup_layout = QtWidgets.QVBoxLayout()
self.popup_layout.addLayout(self.checkbox_layout)
self.popup_layout.addWidget(self.button_box)
self.setLayout(self.popup_layout)
def finalize_selected_plots(self):
if self.option1.isChecked() == False:
self.selected_plots[0] = 0
if self.option2.isChecked() == False:
self.selected_plots[1] = 0
return self.selected_plots
def clicked_ok(self):
print("clicked ok")
self.plots = self.finalize_selected_plots()
# Send selection back to Results Window
# main_window = MainWindow()
# static_reply = self.plots
# self.popup_response.connect(main_window.popup_input)
# self.popup_response.emit(static_reply)
self.plots = [1,1]
self.close()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
#self.exPopup = Options()
self.data_to_plot = [[1, 5, 10], [2, 4, 6], [6, 4, 2]] # Dummy values
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
self.button_options = QtWidgets.QPushButton('Plot Options', self)
#self.button_options.clicked.connect(self.open_options)
self.button_options.clicked.connect(self.popup_input)
self.option_layout = QtWidgets.QHBoxLayout()
self.option_layout.addWidget(self.button_options)
self.layout = QtWidgets.QGridLayout(self._main)
self.layout.addLayout(self.option_layout, 0, 2)
# def open_options(self):
# self.exPopup.show()
#@QtCore.pyqtSlot(object)
def popup_input(self):
plot_title_font_size = 15
data = self.data_to_plot
self.grab_popup = Options(self)
if self.grab_popup.exec():
print("Pressed ok")
if reply[0] != 0:
self.figure_xy1 = FigureCanvas(Figure(figsize=(5, 5)))
self._figure1 = self.figure_xy1.figure.subplots()
self._figure1.grid()
self.layout.addWidget(self.figure_xy1, 1, 3)
self.figure_label1 = QLabel('Test Plot 1', self)
self.figure_label1.setFont(QFont('Times', plot_title_font_size))
self.figure_label1.setAlignment(QtCore.Qt.AlignLeft)
self.layout.addWidget(self.figure_label1, 1, 4)
x = data[0]
y = data[1]
self._figure1.plot(x, y, '-')
self._figure1.set_xlabel('x')
self._figure1.set_ylabel('y1')
self._figure1.figure.canvas.draw()
if reply[1] != 0:
self.figure_xy2 = FigureCanvas(Figure(figsize=(5, 5)))
self._figure2 = self.figure_xy2.figure.subplots()
self._figure2.grid()
self.layout.addWidget(self.figure_xy2, 2, 3)
self.figure_label2 = QLabel('Test Plot 2', self)
self.figure_label2.setFont(QFont('Times', plot_title_font_size))
self.figure_label2.setAlignment(QtCore.Qt.AlignLeft)
self.layout.addWidget(self.figure_label2, 2, 4)
x = data[0]
y = data[2]
self._figure2.plot(x, y, '-')
self._figure2.set_xlabel('x')
self._figure2.set_ylabel('y2')
self._figure2.figure.canvas.draw()
else:
print("Pressed Cancel")
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/454814.html
