在其他文件中将Qt Widget引用到其他Python类中

问题描述 投票:0回答:1

我有两个不同的Python文件。一个是GUI细节,另一个是使用Code来使用Watchdog API监视文件夹

GUI Py文件:

# -*- 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 Data frame的数据显示到我的GUI表Widget中,而不是显示到我的WatchDog实现文件中由DataFrameTableWidget Class继承的QTableWidget中。

我在想,以某种方式从GUI初始化带有QTableWidget的DataFrameTableWidget类可能会起作用。但我不确定我是否可以将QTableWidget传递给DataFrameTaleWidget类初始化(即.init)函数,以便我可以将我的GUI表格Widget引用到我的Watchdog实现文件中。

我尽力在这里解决我的问题。但如果仍然面临问题,同时理解我将编辑并将尝试使其更清楚。

谢谢!

更新代码版本

CSV excel GUI.朋友

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.朋友

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)
python pyqt pyqt5
1个回答
1
投票

您的代码有以下错误:

  • 使用行:w = DataFrameTableWidget(self.tableWidget),你只是指出Data Frame qTableWidget是QTableWidget的子代(也就是说,它将放在widget中),并且不会替换它。
  • watcher = Watcher(self.file_Name)是一个局部变量,在完成执行start_button_click时将被删除。

假设您的代码在添加GUI之前有效,我将进行以下修改:

  1. 通过self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)更改self.tableWidget = DataFrameTableWidget(self.centralwidget),如果你有.ui它会教你使用如何通过Qt Designer设置新的小部件。
  2. 实现set_filename方法,这样每次按下按钮都不需要创建新的Watcher对象。
  3. 将对象设为类的对象观察者成员。

main_file.朋友

# ...

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_())
© www.soinside.com 2019 - 2024. All rights reserved.