Python 如何使用PyQt组织布局
我对PyQt非常陌生,我发现在窗口中订购小部件非常困难 我有一个实时更新的绘图,一个每次用户单击绘图时都会更新的表,还有两个按钮(开始/停止) 当前布局的行为方式如下: 我希望它看起来像这样: 其中“其他小部件”对应于我将在工作时添加的未来小部件(如滑块或下拉列表)。表也应该尽可能薄,以最大限度地扩大绘图的大小,并且不让表占用不必要的空间。我当前的代码如下(它是独立的): 导入系统 将numpy作为np导入 从matplotlib.backends.qt\u compat导入QtWidgets 从matplotlib.backends.backend_qt5agg导入FigureCanvas 从matplotlib.figure导入图形 def onclick(事件): 全球点击 单击.append(event.xdata) 返回 类ApplicationWindow(QtWidgets.QMainWindow): 定义初始化(自): 超级(应用程序窗口,自我)。\uuuu初始化 self.\u title='Prueba实时' self.setWindowTitle(self.\u title) self.\u main=qtwidts.QWidget() self.setCentralWidget(self.\u main) layout=qtwidts.QHBoxLayout(self.\u main) 动态画布=图形画布(图(figsize=(10,10))) layout.addWidget(动态_画布) self.\u dynamic\u ax=dynamic\u canvas.figure.subplots() dynamic\u canvas.figure.canvas.mpl\u connect('button\u press\u event',onclick) self.\u dynamic\u ax.grid() self.\u timer=dynamic\u canvas.new\u timer( 100,[(自我更新窗口,(),{}] self.\u timer.start() button_stop=qtwidts.QPushButton('stop',self) layout.addWidget(按钮\停止) 按钮\u停止。单击。连接(按下自身按钮) button_start=qtwidts.QPushButton('start',self) layout.addWidget(按钮启动) 按钮\u开始。点击。连接(按下自身按钮) self.table_clicks=qtwidts.QTableWidget() self.table_clicks.setRowCount(0) self.table_clicks.setColumnCount(2) layout.addWidget(self.table_单击) def按钮按下(自身): 如果self.sender().text()=“停止”: self.\u timer.stop() 如果self.sender().text()=“开始”: self.\u timer.start() 定义更新窗口(自): self.\u dynamic\u ax.clear() 全局x、y1、y2、y3、N、计数、最后点击次数 x、 附加(x[计数]0.01) y1.append(np.random.random()) idx\u inf=max([count\u iter-N,0]) 如果最后一次点击次数Python 如何使用PyQt组织布局,python,matplotlib,pyqt,widget,pyqt5,Python,Matplotlib,Pyqt,Widget,Pyqt5,我对PyQt非常陌生,我发现在窗口中订购小部件非常困难 我有一个实时更新的绘图,一个每次用户单击绘图时都会更新的表,还有两个按钮(开始/停止) 当前布局的行为方式如下: 我希望它看起来像这样: 其中“其他小部件”对应于我将在工作时添加的未来小部件(如滑块或下拉列表)。表也应该尽可能薄,以最大限度地扩大绘图的大小,并且不让表占用不必要的空间。我当前的代码如下(它是独立的): 导入系统 将numpy作为np导入 从matplotlib.backends.qt\u compat导入QtWidget
QGridLayout
QGridLayout具有addWidget()方法,您可以在其中指示小部件将放置的行和列,addLayout()也是如此
void QGridLayout::addWidget(QWidget*widget,int行,int列,Qt::Alignment=…)
void QGridLayout::addLayout(QLayout*布局,int行,int列,Qt::对齐=…)
在您的情况下,结构应如下所示:
QGridLayout
├── Plot (0, 0)
├── Table (0, 1)
├── Other Widgets (1, 0)
└── QVBoxLayout (1, 1)
├── button_start
└── button_stop
import sys
import numpy as np
from matplotlib.backends.qt_compat import QtCore, QtGui, QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure
def onclick(event):
global clicks
clicks.append(event.xdata)
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super(ApplicationWindow, self).__init__()
self._title = 'Prueba real-time'
self.setWindowTitle(self._title)
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
dynamic_canvas = FigureCanvas(Figure(figsize=(10, 10)))
self._dynamic_ax = dynamic_canvas.figure.subplots()
dynamic_canvas.figure.canvas.mpl_connect('button_press_event', onclick)
self._dynamic_ax.grid()
self._timer = dynamic_canvas.new_timer(
100, [(self._update_window, (), {})])
self._timer.start()
button_stop = QtWidgets.QPushButton('Stop', self)
button_stop.clicked.connect(self._timer.stop)
button_start = QtWidgets.QPushButton('Start', self)
button_start.clicked.connect(self._timer.start)
self.table_clicks = QtWidgets.QTableWidget(0, 2)
self.table_clicks.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
other_widget = QtWidgets.QLabel("Other widgets",
font=QtGui.QFont("Times", 60, QtGui.QFont.Bold),
alignment=QtCore.Qt.AlignCenter)
# layouts
layout = QtWidgets.QGridLayout(self._main)
layout.addWidget(dynamic_canvas, 0, 0)
layout.addWidget(self.table_clicks, 0, 1)
layout.addWidget(other_widget, 1, 0)
button_layout = QtWidgets.QVBoxLayout()
button_layout.addWidget(button_stop)
button_layout.addWidget(button_start)
layout.addLayout(button_layout, 1, 1)
layout.setColumnStretch(0, 2)
layout.setColumnStretch(1, 1)
def _update_window(self):
self._dynamic_ax.clear()
global x, y1, y2, y3, N, count_iter, last_number_clicks
x.append(x[count_iter] + 0.01)
y1.append(np.random.random())
idx_inf = max([count_iter-N, 0])
if last_number_clicks < len(clicks):
for new_click in clicks[last_number_clicks:(len(clicks))]:
rowPosition = self.table_clicks.rowCount()
self.table_clicks.insertRow(rowPosition)
self.table_clicks.setItem(rowPosition,0, QtWidgets.QTableWidgetItem(str(new_click)))
self.table_clicks.setItem(rowPosition,1, QtWidgets.QTableWidgetItem("Descripcion"))
last_number_clicks = len(clicks)
self._dynamic_ax.plot(x[idx_inf:count_iter], y1[idx_inf:count_iter],'-o', color='b')
count_iter += 1
self._dynamic_ax.figure.canvas.draw()
#%%
if __name__ == "__main__":
pressed_key = {}
clicks = []
last_number_clicks = len(clicks)
N = 25
y1 = [np.random.random()]
x = [0]
count_iter = 0
qapp = QtWidgets.QApplication(sys.argv)
app = ApplicationWindow()
app.show()
sys.exit(qapp.exec_())
然后,您可以使用setColumnStretch()
指示每列的权重,也就是说,列宽将与第2列的宽度成比例:
考虑到上述情况,我们有以下几点:
QGridLayout
├── Plot (0, 0)
├── Table (0, 1)
├── Other Widgets (1, 0)
└── QVBoxLayout (1, 1)
├── button_start
└── button_stop
import sys
import numpy as np
from matplotlib.backends.qt_compat import QtCore, QtGui, QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure
def onclick(event):
global clicks
clicks.append(event.xdata)
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super(ApplicationWindow, self).__init__()
self._title = 'Prueba real-time'
self.setWindowTitle(self._title)
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
dynamic_canvas = FigureCanvas(Figure(figsize=(10, 10)))
self._dynamic_ax = dynamic_canvas.figure.subplots()
dynamic_canvas.figure.canvas.mpl_connect('button_press_event', onclick)
self._dynamic_ax.grid()
self._timer = dynamic_canvas.new_timer(
100, [(self._update_window, (), {})])
self._timer.start()
button_stop = QtWidgets.QPushButton('Stop', self)
button_stop.clicked.connect(self._timer.stop)
button_start = QtWidgets.QPushButton('Start', self)
button_start.clicked.connect(self._timer.start)
self.table_clicks = QtWidgets.QTableWidget(0, 2)
self.table_clicks.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
other_widget = QtWidgets.QLabel("Other widgets",
font=QtGui.QFont("Times", 60, QtGui.QFont.Bold),
alignment=QtCore.Qt.AlignCenter)
# layouts
layout = QtWidgets.QGridLayout(self._main)
layout.addWidget(dynamic_canvas, 0, 0)
layout.addWidget(self.table_clicks, 0, 1)
layout.addWidget(other_widget, 1, 0)
button_layout = QtWidgets.QVBoxLayout()
button_layout.addWidget(button_stop)
button_layout.addWidget(button_start)
layout.addLayout(button_layout, 1, 1)
layout.setColumnStretch(0, 2)
layout.setColumnStretch(1, 1)
def _update_window(self):
self._dynamic_ax.clear()
global x, y1, y2, y3, N, count_iter, last_number_clicks
x.append(x[count_iter] + 0.01)
y1.append(np.random.random())
idx_inf = max([count_iter-N, 0])
if last_number_clicks < len(clicks):
for new_click in clicks[last_number_clicks:(len(clicks))]:
rowPosition = self.table_clicks.rowCount()
self.table_clicks.insertRow(rowPosition)
self.table_clicks.setItem(rowPosition,0, QtWidgets.QTableWidgetItem(str(new_click)))
self.table_clicks.setItem(rowPosition,1, QtWidgets.QTableWidgetItem("Descripcion"))
last_number_clicks = len(clicks)
self._dynamic_ax.plot(x[idx_inf:count_iter], y1[idx_inf:count_iter],'-o', color='b')
count_iter += 1
self._dynamic_ax.figure.canvas.draw()
#%%
if __name__ == "__main__":
pressed_key = {}
clicks = []
last_number_clicks = len(clicks)
N = 25
y1 = [np.random.random()]
x = [0]
count_iter = 0
qapp = QtWidgets.QApplication(sys.argv)
app = ApplicationWindow()
app.show()
sys.exit(qapp.exec_())
导入系统
将numpy作为np导入
从matplotlib.backends.qt_compat导入QtCore、QtGui、QtWidgets
从matplotlib.backends.backend_qt5agg导入FigureCanvas
从matplotlib.figure导入图形
def onclick(事件):
全球点击
单击.append(event.xdata)
类ApplicationWindow(QtWidgets.QMainWindow):
定义初始化(自):
超级(应用程序窗口,自我)。\uuuu初始化
self.\u title='Prueba实时'
self.setWindowTitle(self.\u title)
self.\u main=qtwidts.QWidget()
self.setCentralWidget(self.\u main)
动态画布=图形画布(图(figsize=(10,10)))
self.\u dynamic\u ax=dynamic\u canvas.figure.subplots()
dynamic\u canvas.figure.canvas.mpl\u connect('button\u press\u event',onclick)
self.\u dynamic\u ax.grid()
self.\u timer=dynamic\u canvas.new\u timer(
100,[(自我更新窗口,(),{}]
self.\u timer.start()
button_stop=qtwidts.QPushButton('stop',self)
按钮\u停止。点击。连接(自。\u定时器。停止)
button_start=qtwidts.QPushButton('start',self)
按钮\u开始。点击。连接(自。\u定时器。开始)
self.table_clicks=QtWidgets.QTableWidget(0,2)
self.table_clicks.horizontalHeader().setSectionResizeMode(qtwidts.QHeaderView.Stretch)
other_widget=qtwidts.QLabel(“其他小部件”,
font=QtGui.QFont(“Times”,60,QtGui.QFont.Bold),
对齐=QtCore.Qt.AlignCenter)
#布局
layout=qtwidts.QGridLayout(self.\u main)
layout.addWidget(动态画布,0,0)
layout.addWidget(self.table_单击,0,1)
layout.addWidget(其他窗口)
import sys
import numpy as np
from matplotlib.backends.qt_compat import QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure
def onclick(event):
global clicks
clicks.append(event.xdata)
return
class TableWidget(QtWidgets.QWidget):
def __init__(self,parent,*args,**kwargs):
super().__init__(*args,**kwargs)
self.parent = parent
layout = QtWidgets.QVBoxLayout(self)
self.table_clicks = QtWidgets.QTableWidget()
self.table_clicks.setRowCount(0)
self.table_clicks.setColumnCount(2)
layout.addWidget(self.table_clicks)
button_widget = QtWidgets.QWidget(self)
layout.addWidget(button_widget)
button_layout = QtWidgets.QHBoxLayout(button_widget)
button_stop = QtWidgets.QPushButton('Stop', self)
button_layout.addWidget(button_stop)
button_stop.clicked.connect(self.parent.plot_widget.button_pressed)
button_start = QtWidgets.QPushButton('Start', self)
button_layout.addWidget(button_start)
button_start.clicked.connect(self.parent.plot_widget.button_pressed)
class PlotWidget(QtWidgets.QWidget):
def __init__(self,parent,*args,**kwargs):
super().__init__(parent,*args,**kwargs)
self.parent = parent
layout = QtWidgets.QVBoxLayout(self)
dynamic_canvas = FigureCanvas(Figure(figsize=(10, 10)))
layout.addWidget(dynamic_canvas)
self._dynamic_ax = dynamic_canvas.figure.subplots()
dynamic_canvas.figure.canvas.mpl_connect('button_press_event', onclick)
self._dynamic_ax.grid()
self._timer = dynamic_canvas.new_timer(
100, [(self._update_window, (), {})])
self._timer.start()
def button_pressed(self):
if self.sender().text() == 'Stop':
self._timer.stop()
if self.sender().text() == 'Start':
self._timer.start()
def _update_window(self):
self._dynamic_ax.clear()
global x, y1, y2, y3, N, count_iter, last_number_clicks
x.append(x[count_iter] + 0.01)
y1.append(np.random.random())
idx_inf = max([count_iter-N, 0])
if last_number_clicks < len(clicks):
for new_click in clicks[last_number_clicks:(len(clicks))]:
rowPosition = self.parent.table_widget.table_clicks.rowCount()
self.parent.table_widget.table_clicks.insertRow(rowPosition)
self.parent.table_widget.table_clicks.setItem(rowPosition,0, QtWidgets.QTableWidgetItem(str(new_click)))
self.parent.table_widget.table_clicks.setItem(rowPosition,1, QtWidgets.QTableWidgetItem("Descripcion"))
last_number_clicks = len(clicks)
self._dynamic_ax.plot(x[idx_inf:count_iter], y1[idx_inf:count_iter],'-o', color='b')
count_iter += 1
self._dynamic_ax.figure.canvas.draw()
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super(ApplicationWindow, self).__init__()
self._title = 'Prueba real-time'
self.setWindowTitle(self._title)
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
main_layout = QtWidgets.QHBoxLayout(self._main)
self.plot_widget = PlotWidget(self)
main_layout.addWidget(self.plot_widget)
self.table_widget = TableWidget(self)
main_layout.addWidget(self.table_widget)
#%%
if __name__ == "__main__":
pressed_key = {}
clicks = []
last_number_clicks = len(clicks)
N = 25
y1 = [np.random.random()]
x = [0]
count_iter = 0
qapp = QtWidgets.QApplication(sys.argv)
app = ApplicationWindow()
app.show()
qapp.exec_()