python - 将 Qt Widget 引用到其他文件中的其他 Python 类中
问题描述
我有两个不同的 Python 文件。一个具有 GUI 详细信息,另一个具有使用 Watchdog API 监视文件夹的代码
图形用户界面文件:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'csvExcel.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
import os
from Main_File import Watcher, DataFrameTableWidget
class Ui_MainWindow(object):
def __init__(self):
self.file_Name = None
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
self.start_button = QtWidgets.QPushButton(self.centralwidget)
self.start_button.setAutoFillBackground(False)
self.start_button.setAutoDefault(False)
self.start_button.setDefault(False)
self.start_button.setFlat(False)
self.start_button.setObjectName("start_button")
self.start_button.clicked.connect(lambda: self.start_button_click())
self.gridLayout_2.addWidget(self.start_button, 0, 0, 1, 1)
self.Br_button = QtWidgets.QPushButton(self.centralwidget)
self.Br_button.setObjectName("Br_button")
self.Br_button.clicked.connect(lambda: self.browse_button())
self.gridLayout_2.addWidget(self.Br_button, 2, 0, 1, 1)
self.label = QtWidgets.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setObjectName("label")
self.gridLayout_2.addWidget(self.label, 2, 1, 1, 1, QtCore.Qt.AlignHCenter)
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(0)
self.tableWidget.setRowCount(0)
self.gridLayout_2.addWidget(self.tableWidget, 3, 0, 1, 2)
self.gridLayout.addLayout(self.gridLayout_2, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.start_button.setToolTip(_translate("MainWindow", "Start The Program"))
self.start_button.setText(_translate("MainWindow", "Start"))
self.Br_button.setToolTip(_translate("MainWindow", "Browse the File Location to Watch on"))
self.Br_button.setText(_translate("MainWindow", "Browse"))
self.label.setText(_translate("MainWindow", "Sensor CSV To Excel"))
def start_button_click(self):
watcher = Watcher(self.file_Name)
if self.start_button.text() == "Start":
self.start_button.setText("Stop")
w = DataFrameTableWidget(self.tableWidget)
watcher.emitter.newDataFrameSignal.connect(w.append_dataframe)
watcher.run()
elif self.start_button.text() == "Stop":
self.start_button.setText("Start")
watcher.stop_watcher()
def browse_button(self):
self.file_Name = QtWidgets.QFileDialog.getExistingDirectory(None, 'Open working directory', os.getcwd(), QtWidgets.QFileDialog.ShowDirsOnly)
print(self.file_Name)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
具有看门狗实现的 Python 代码文件
import os
import pandas as pd
from PyQt5 import QtCore, QtWidgets
from watchdog.events import PatternMatchingEventHandler
from watchdog.observers import Observer
import time
from Append_Function import append_df_to_excel
class Emitter(QtCore.QObject):
newDataFrameSignal = QtCore.pyqtSignal(pd.DataFrame)
class Watcher:
def __init__(self, filename):
self.watch_dir = os.getcwd()
self.directory_to_watch = os.path.join(self.watch_dir, filename)
self.emitter = Emitter()
self.observer = Observer()
self.event_handler = Handler(
emitter=self.emitter,
patterns=["*.CSV"],
ignore_patterns=["*.tmp"],
ignore_directories=True
)
def run(self):
self.observer.schedule(self.event_handler, self.directory_to_watch, recursive=False)
self.observer.start()
def stop_watcher(self):
self.observer.stop()
class Handler(PatternMatchingEventHandler):
def __init__(self, *args, emitter=None, **kwargs):
super(Handler, self).__init__(*args, **kwargs)
self._emitter = emitter
self.file_name = time.strftime("%Y%m%d-%H%M%S")+".xlsx"
def on_any_event(self, event):
if event.is_directory:
return None
elif event.event_type == 'created':
# Take any action here when a file is first created.
print("Received created event - %s." % event.src_path)
if os.path.isfile(os.path.join(os.getcwd(), self.file_name)):
append_df_to_excel(os.path.join(os.getcwd(), self.file_name),
pd.read_csv(event.src_path, header=1, index_col=0))
df = pd.read_csv(event.src_path, header=1)
else:
append_df_to_excel(os.path.join(os.getcwd(), self.file_name),
pd.read_csv(event.src_path, header=0, index_col=0))
df = pd.read_csv(event.src_path, header=0)
self._emitter.newDataFrameSignal.emit(df.copy())
df.set_index(df.columns.values.tolist()[0], inplace=True)
elif event.event_type == 'modified':
print("Modified created event - %s." % event.src_path)
if os.path.isfile(os.path.join(os.getcwd(), self.file_name)):
append_df_to_excel(os.path.join(os.getcwd(), self.file_name),
pd.read_csv(event.src_path, header=1, index_col=0))
df = pd.read_csv(event.src_path, header=1)
else:
append_df_to_excel(os.path.join(os.getcwd(), self.file_name),
pd.read_csv(event.src_path, header=0, index_col=0))
df = pd.read_csv(event.src_path, header=0)
self._emitter.newDataFrameSignal.emit(df.copy())
df.set_index(df.columns.values.tolist()[0], inplace=True)
class DataFrameTableWidget(QtWidgets.QTableWidget):
@QtCore.pyqtSlot(pd.DataFrame)
def append_dataframe(self, df):
df = df.copy()
if df.columns.size > self.columnCount():
self.setColumnCount(df.columns.size)
r = self.rowCount()
self.insertRow(r)
for c, column in enumerate(df):
it = QtWidgets.QTableWidgetItem(column)
self.setItem(r, c, it)
i = self.rowCount()
for r, row in df.iterrows():
self.insertRow(self.rowCount())
for c, (column, value) in enumerate(row.iteritems()):
it = QtWidgets.QTableWidgetItem(str(value))
self.setItem(i+r, c, it)
在此文件中,您可以看到我使用了一个函数“Append_Function”,它实际上是将数据附加到 Excel 文件中(如果需要,我将编辑以添加函数代码)。
我的问题
在 Watchdog 实现文件中,您可以看到该 DataFrameTableWidget 类中有一个自定义 Pyslot。生成数据框时它会激活。相应地,来自数据框的数据显示在 QWidget 表中,因为 DataFrameTableWidget 类继承了 QTableWidget。
现在你可以看到我已经为我的应用程序制作了一个单独的 GUI,它有一个表格小部件。我希望将 pandas 数据框中的数据显示到我的 GUI 表小部件中,而不是显示到我的 WatchDog 实现文件中的 DataFrameTableWidget 类继承的 QTableWidget 中。
我在想以某种方式使用 GUI 中的 QTableWidget 初始化 DataFrameTableWidget 类可能会起作用。但我不确定我是否可以将 QTableWidget 传递给 DataFrameTaleWidget 类初始化(即init)函数,以便我可以将我的 GUI 表小部件引用到我的看门狗实现文件中。
我尽力在这里弄清楚我的问题。但是,如果在理解时仍然遇到问题,我将编辑并尝试使其更清晰。
谢谢!
更新代码版本
csvExcelGUI.py
from PyQt5 import QtCore, QtGui, QtWidgets
import os
from Main_File import Watcher, DataFrameTableWidget
class Ui_MainWindow(object):
def __init__(self):
self.file_Name = None
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
self.start_button = QtWidgets.QPushButton(self.centralwidget)
self.start_button.setAutoFillBackground(False)
self.start_button.setAutoDefault(False)
self.start_button.setDefault(False)
self.start_button.setFlat(False)
self.start_button.setObjectName("start_button")
#self.start_button.clicked.connect(lambda: self.start_button_click())
self.gridLayout_2.addWidget(self.start_button, 0, 0, 1, 1)
self.Br_button = QtWidgets.QPushButton(self.centralwidget)
self.Br_button.setObjectName("Br_button")
self.Br_button.clicked.connect(lambda: self.browse_button())
self.gridLayout_2.addWidget(self.Br_button, 2, 0, 1, 1)
self.label = QtWidgets.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setObjectName("label")
self.gridLayout_2.addWidget(self.label, 2, 1, 1, 1, QtCore.Qt.AlignHCenter)
#self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget = DataFrameTableWidget(self.centralwidget)
self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(0)
self.tableWidget.setRowCount(0)
self.gridLayout_2.addWidget(self.tableWidget, 3, 0, 1, 2)
self.gridLayout.addLayout(self.gridLayout_2, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.start_button.setToolTip(_translate("MainWindow", "Start The Program"))
self.start_button.setText(_translate("MainWindow", "Start"))
self.Br_button.setToolTip(_translate("MainWindow", "Browse the File Location to Watch on"))
self.Br_button.setText(_translate("MainWindow", "Browse"))
self.label.setText(_translate("MainWindow", "Sensor CSV To Excel"))
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.start_button.clicked.connect(self.start_button_click)
self.watcher = Watcher()
self.watcher.emitter.newDataFrameSignal.connect(self.tableWidget.append_dataframe)
self.file_Name = ""
def start_button_click(self):
self.watcher.set_filename(self.file_Name)
if self.start_button.text() == "Start":
self.start_button.setText("Stop")
self.watcher.run()
elif self.start_button.text() == "Stop":
self.start_button.setText("Start")
self.watcher.stop_watcher()
def browse_button(self):
self.file_Name = QtWidgets.QFileDialog.getExistingDirectory(None, 'Open working directory', os.getcwd(), QtWidgets.QFileDialog.ShowDirsOnly)
print(self.file_Name)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
# MainWindow = QtWidgets.QMainWindow()
# ui = Ui_MainWindow()
# ui.setupUi(MainWindow)
# MainWindow.show()
w = MainWindow()
w.show()
sys.exit(app.exec_())
Main_File.py
import os
import pandas as pd
from PyQt5 import QtCore, QtWidgets
from watchdog.events import PatternMatchingEventHandler
from watchdog.observers import Observer
import time
from Append_Function import append_df_to_excel
class Emitter(QtCore.QObject):
newDataFrameSignal = QtCore.pyqtSignal(pd.DataFrame)
class Watcher:
def __init__(self):
self.watch_dir = os.getcwd()
self.directory_to_watch = None
self.emitter = Emitter()
self.observer = Observer()
self.event_handler = Handler(
emitter=self.emitter,
patterns=["*.CSV"],
ignore_patterns=["*.tmp"],
ignore_directories=True
)
def set_filename(self, filename):
self.directory_to_watch = os.path.join(self.watch_dir, filename)
def run(self):
self.observer.schedule(self.event_handler, self.directory_to_watch, recursive=False)
self.observer.start()
def stop_watcher(self):
self.observer.stop()
class Handler(PatternMatchingEventHandler):
def __init__(self, *args, emitter=None, **kwargs):
super(Handler, self).__init__(*args, **kwargs)
self._emitter = emitter
self.file_name = time.strftime("%Y%m%d-%H%M%S")+".xlsx"
def on_any_event(self, event):
if event.is_directory:
return None
elif event.event_type == 'created':
# Take any action here when a file is first created.
print("Received created event - %s." % event.src_path)
if os.path.isfile(os.path.join(os.getcwd(), self.file_name)):
append_df_to_excel(os.path.join(os.getcwd(), self.file_name),
pd.read_csv(event.src_path, header=1, index_col=0))
df = pd.read_csv(event.src_path, header=1)
else:
append_df_to_excel(os.path.join(os.getcwd(), self.file_name),
pd.read_csv(event.src_path, header=0, index_col=0))
df = pd.read_csv(event.src_path, header=0)
self._emitter.newDataFrameSignal.emit(df.copy())
df.set_index(df.columns.values.tolist()[0], inplace=True)
elif event.event_type == 'modified':
print("Modified created event - %s." % event.src_path)
if os.path.isfile(os.path.join(os.getcwd(), self.file_name)):
append_df_to_excel(os.path.join(os.getcwd(), self.file_name),
pd.read_csv(event.src_path, header=1, index_col=0))
df = pd.read_csv(event.src_path, header=1)
else:
append_df_to_excel(os.path.join(os.getcwd(), self.file_name),
pd.read_csv(event.src_path, header=0, index_col=0))
df = pd.read_csv(event.src_path, header=0)
self._emitter.newDataFrameSignal.emit(df.copy())
df.set_index(df.columns.values.tolist()[0], inplace=True)
class DataFrameTableWidget(QtWidgets.QTableWidget):
@QtCore.pyqtSlot(pd.DataFrame)
def append_dataframe(self, df):
df = df.copy()
if df.columns.size > self.columnCount():
self.setColumnCount(df.columns.size)
r = self.rowCount()
self.insertRow(r)
for c, column in enumerate(df):
it = QtWidgets.QTableWidgetItem(column)
self.setItem(r, c, it)
i = self.rowCount()
for r, row in df.iterrows():
self.insertRow(self.rowCount())
for c, (column, value) in enumerate(row.iteritems()):
it = QtWidgets.QTableWidgetItem(str(value))
self.setItem(i+r, c, it)
解决方案
您的代码有以下错误:
使用该行:
w = DataFrameTableWidget(self.tableWidget)
,您只是指出 Data Frame qTableWidget 是 QTableWidget 的子级(即,它将被放置在小部件内),并且不会替换它。watcher = Watcher(self.file_Name)
是一个局部变量,当它执行完 start_button_click 时将被删除。
假设您的代码在添加 GUI 之前可以工作,我将进行以下修改:
- 更改
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
为self.tableWidget = DataFrameTableWidget(self.centralwidget)
,如果您有 .ui,它将教您如何使用如何通过 Qt Designer 设置新的小部件。 - 实现一个 set_filename 方法,这样就不需要在每次按下按钮时都创建一个新的 Watcher 对象。
- 使对象成为类的对象观察者成员。
Main_File.py
# ...
class Watcher:
def __init__(self):
self.watch_dir = os.getcwd()
self.emitter = Emitter()
self.observer = Observer()
self.event_handler = Handler(
emitter=self.emitter,
patterns=["*.CSV"],
ignore_patterns=["*.tmp"],
ignore_directories=True
)
def set_filename(self, filename):
self.directory_to_watch = os.path.join(self.watch_dir, filename)
# ...
主文件
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'csvExcel.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
import os
from Main_File import Watcher, DataFrameTableWidget
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
self.start_button = QtWidgets.QPushButton(self.centralwidget)
self.start_button.setAutoFillBackground(False)
self.start_button.setAutoDefault(False)
self.start_button.setDefault(False)
self.start_button.setFlat(False)
self.start_button.setObjectName("start_button")
self.gridLayout_2.addWidget(self.start_button, 0, 0, 1, 1)
self.Br_button = QtWidgets.QPushButton(self.centralwidget)
self.Br_button.setObjectName("Br_button")
self.Br_button.clicked.connect(lambda: self.browse_button())
self.gridLayout_2.addWidget(self.Br_button, 2, 0, 1, 1)
self.label = QtWidgets.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setObjectName("label")
self.gridLayout_2.addWidget(self.label, 2, 1, 1, 1, QtCore.Qt.AlignHCenter)
self.tableWidget = DataFrameTableWidget(self.centralwidget)
self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(0)
self.tableWidget.setRowCount(0)
self.gridLayout_2.addWidget(self.tableWidget, 3, 0, 1, 2)
self.gridLayout.addLayout(self.gridLayout_2, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.start_button.setToolTip(_translate("MainWindow", "Start The Program"))
self.start_button.setText(_translate("MainWindow", "Start"))
self.Br_button.setToolTip(_translate("MainWindow", "Browse the File Location to Watch on"))
self.Br_button.setText(_translate("MainWindow", "Browse"))
self.label.setText(_translate("MainWindow", "Sensor CSV To Excel"))
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.start_button.clicked.connect(self.start_button_click)
self.watcher = Watcher()
self.watcher.emitter.newDataFrameSignal.connect(self.tableWidget.append_dataframe)
self.file_Name = ""
def start_button_click(self):
self.watcher.set_filename(self.file_Name)
if self.start_button.text() == "Start":
self.start_button.setText("Stop")
self.watcher.run()
elif self.start_button.text() == "Stop":
self.start_button.setText("Start")
self.watcher.stop_watcher()
def browse_button(self):
self.file_Name = QtWidgets.QFileDialog.getExistingDirectory(None, 'Open working directory', os.getcwd(), QtWidgets.QFileDialog.ShowDirsOnly)
print(self.file_Name)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
推荐阅读
- python - 如何使用 pycrypto 执行河豚解密
- office365 - Microsoft graph 批量调用 OneNote 页面重命名失败,并显示消息“Invalid JSON body for request id”
- ruby-on-rails - 将字段增加一些数字而不更新时间戳
- elasticsearch - 如何从登录logstash配置中检索JSON对象?
- python - 这段代码中的“count”在审查一个单词时做了什么?
- html - 单选按钮是否应该包含在标签标签内?
- python - python regex 需要帮助来枚举数据
- php - 无法使用我的 SQL 查询调试语法错误
- php - WordPress 中的 HTTP 错误 403 禁止问题
- java - 如何在groovy类中调用接口的默认方法