我没有像你们一样的丰富经验,但是我尽力实现一些小型项目的兴趣。可能是你们中的一些人对我的小程序的代码感到震惊,并且还有很多改进之处。我请你谅解。我花了3个月的时间编写此程序,但现在我有了一些布局,我不能再走了。
问题
以前,小部件在主窗口中具有绝对位置。一切都很好。当我开始将所有小部件实现为正确的布局时,QTableWidget和Matplot不再更新小部件。当我在中输入要应用的值时,GUI不会发生任何反应,但数据框正确。我重新启动程序,输入的值将应用于QTableWidget和Matplot。
尝试
我开始阅读并尝试使用信号和插槽将信号发送到事件循环。还有我尝试过的线程和模型,但可能不是正确的方式。什么是解决此问题的好方法。 感谢您的帮助。
代码
import os, sys, matplotlib
from PyQt5.QtGui import QIcon
from PyQt5 import QtGui, QtWidgets, QtCore
from PyQt5.QtWidgets import qApp, QApplication, QMainWindow, QWidget, QHBoxLayout, QVBoxLayout, QAction, QFileDialog, \
QLineEdit, QPushButton, QDateEdit, QComboBox, QTableWidget, QTableWidgetItem
from PyQt5.QtCore import Qt, pyqtSlot
import pandas as pd
import numpy as np
from matplotlib import figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt
class MyForm(QMainWindow):
def __init__(self):
super(MyForm, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(50, 50, 1600, 1200)
self.resize(1350, 1200)
self.move(0, 120)
self.setWindowTitle('Asset allocation')
self.setWindowIcon(QIcon('icon.png'))
self.tableView = ShowTable(self)
self.chart = MatplotlibFigure(self)
self.inputMask = InputValues(self)
widget=QWidget()
gridtotoal=QHBoxLayout(widget)
vtotal=QVBoxLayout()
vtotal.addWidget(self.inputMask)
vtotal.addWidget(self.tableView, 1, alignment=Qt.AlignTop)
gridtotoal.addLayout(vtotal)
gridtotoal.addWidget(self.chart, 5)
self.setCentralWidget(widget)
class InputValues(QWidget):
def __init__(self, parent):
super().__init__(parent)
self.initUI()
def initUI(self):
h1_layout = QHBoxLayout()
h1_layout.addSpacing(20)
self.ledt_value = QLineEdit("", self)
self.ledt_value.setMaximumSize(190, 40)
self.ledt_value.setMinimumSize(190, 40)
self.ledt_value.setCursorPosition(0)
h1_layout.addWidget(self.ledt_value)
self.dateEdit = QDateEdit(self)
self.dateEdit.setMaximumSize(190, 40)
self.dateEdit.setMinimumSize(190, 40)
self.dateEdit.setDate(QtCore.QDate.currentDate())
h1_layout.addWidget(self.dateEdit)
pbtn_apply = QPushButton('Apply', self)
pbtn_apply.setMaximumSize(190, 40)
pbtn_apply.setMinimumSize(190, 40)
pbtn_apply.setObjectName("pbtn_apply")
pbtn_apply.clicked.connect(self.input)
h1_layout.addWidget(pbtn_apply)
h1_layout.addStretch()
self.cmbo_account = QComboBox(self)
self.cmbo_account.setMaximumSize(190, 40)
self.cmbo_account.setMinimumSize(190, 40)
self.cmbo_account.addItem("Current Account", "Currrent")
self.cmbo_account.addItem("Savings Account", "Savings")
self.cmbo_account.addItem("Stock Portfolio", "Stock")
h2_layout = QHBoxLayout()
h2_layout.addSpacing(20)
h2_layout.addWidget(self.cmbo_account,1, alignment=Qt.AlignLeft)
v_layout = QVBoxLayout()
v_layout.addSpacing(35)
v_layout.addLayout(h1_layout)
v_layout.addLayout(h2_layout)
v_layout.addStretch()
self.setLayout(v_layout)
def input(self, index):
value = self.ledt_value.text()
dateinput = self.dateEdit.date().toPyDate()
self.euformat = '%d.%m.%Y'
self.dateeu = dateinput.strftime(self.euformat)
exists = os.path.isfile("data.csv")
if exists:
raw_data = pd.read_csv("data.csv", header=0, delimiter=";")
df = pd.DataFrame(raw_data, columns=["Date", "Current Account", "Savings Account", "Stock Portfolio"])
else:
df = pd.DataFrame(columns=["Date", "Current Account", "Savings Account", "Stock Portfolio"])
dfdate = pd.to_datetime(df["Date"], format="%d.%m.%Y", dayfirst=True)
dfdateeu = dfdate.dt.strftime('%d.%m.%Y')
nanlist = np.argwhere(df[self.cmbo_account.currentData(index)].isnull().values).tolist()
if len(nanlist)!= 0:
df.loc[nanlist[0], self.cmbo_account.currentData(index)] = value
else:
raw_data_app=pd.DataFrame({'Date': [self.dateeu],self.cmbo_account.currentData(index): [value]})
df = df.append(raw_data_app, ignore_index=True, sort=False)
df.to_csv("data.csv", mode='w', header=True, sep=';', index=False)
tabel = ShowTable(self)
tabel.createtable()
canvas = MatplotlibFigure(self)
canvas.plot()
class ShowTable(QTableWidget):
def __init__(self, parent):
super().__init__(parent)
self.initUI()
def initUI(self):
self.tableWidget = QTableWidget()
self.layout = QVBoxLayout()
self.setMinimumSize(647, 400)
self.setMaximumSize(647, 900)
self.layout.addWidget(self.tableWidget)
self.setLayout(self.layout)
self.createtable()
def createtable(self):
exists = os.path.isfile("data.csv")
if exists:
raw_data = pd.read_csv("data.csv", header=0, delimiter=";")
df = pd.DataFrame(raw_data, columns=["Date", "Current Account", "Savings Account", "Stock Portfolio"])
else:
df = pd.DataFrame(columns=["Date", "Current Account", "Savings Account", "Stock Portfolio"])
countrows = len(df)
countcolumn=len(df.columns)
self.tableWidget.setRowCount(countrows)
self.tableWidget.setColumnCount(countcolumn)
for i in range(len(df.index)):
for j in range(len(df.columns)):
self.tableWidget.setItem(i, j, QTableWidgetItem(str(df.iloc[i, j])))
self.tableWidget.resizeRowsToContents()
self.tableWidget.verticalScrollBar().setValue(self.tableWidget.verticalScrollBar().maximum())
self.tableWidget.setHorizontalHeaderLabels(["Date", "Current Account", "Savings Account", "Stock Portfolio"])
class MatplotlibFigure(QWidget):
def __init__(self, parent):
super().__init__(parent)
self.left = 10
self.top = 450
self.width = 1200
self.height = 750
self.setGeometry(self.left, self.top, self.width, self.height)
# self.layout = QVBoxLayout()
plt.style.use('fivethirtyeight')
self.figure = matplotlib.figure.Figure(tight_layout=True)
self.canvas = FigureCanvas(self.figure)
self.toolbar = NavigationToolbar(self.canvas, self)
# self.canvas.setParent(self)
layout = QVBoxLayout(self)
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
self.plot()
self.show()
def plot(self):
exists = os.path.isfile("data.csv")
if exists:
raw_data = pd.read_csv("data.csv", header=0, delimiter=";")
df = pd.DataFrame(raw_data, columns=["Date","Current Account", "Savings Account", "Stock Portfolio"])
df["Date"]=pd.to_datetime(df["Date"], format="%d.%m.%Y", dayfirst=True)
df.set_index(["Date"], drop=True, inplace=True)
df.index = df.index.to_period(freq='M')
# df = pd.DataFrame(raw_data, columns=["Girokonto", "Sparkonto", "Depot"], index=pd.date_range(start='2019/04/01', end='2019/06/01', freq='M'))
self.figure.clf()
ax = self.figure.add_subplot(211)
ax.set_title("Asset allocation", fontsize=20)
ax.set_xlabel("Date", fontsize=13)
ax.set_ylabel("Amount of money", fontsize=13)
ax.tick_params(axis="x", rotation=90)
ax.grid(which='major', axis='both', linestyle='steps', alpha=0.8)
df.plot.area(ax=ax, grid=True)
dfsavings=df.copy()
dfsavings["Assets"] = dfsavings.sum(axis=1)
dfsavings["Savings"] = dfsavings["Assets"].diff(periods=1)
ay = self.figure.add_subplot(212)
ay.set_title("Monthly Savings", fontsize=20)
ay.set_xlabel("Date", fontsize=13)
ay.set_ylabel("Amount of money", fontsize=13)
ay.tick_params(axis="x", rotation=90)
ay.grid(which='major', axis='both', linestyle='steps', alpha=0.8)
dfsavings["Savings"].plot.bar(ax=ay, grid=True)
self.canvas.draw()
else:
pass
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle('fusion')
MainWindow = MyForm()
MainWindow.show()
sys.exit(app.exec_())
CSV文件的样本数据
Date;Current Account;Savings Account;Stock Portfolio
26.01.2019;13811.0;0.0;20000.0
26.02.2019;14322.0;0.0;20000.0
26.03.2019;7863.0;0.0;20000.0
26.04.2019;5087.0;3000.0;20000.0
26.05.2019;7319.0;3000.0;20000.0
26.06.2019;3667.0;5000.0;23000.0
感谢您的努力!