Python Forum
[PyQt] Using Qt to emit a signal (or maybe with QTimer)
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyQt] Using Qt to emit a signal (or maybe with QTimer)
#1
I am trying to send an .hdf5 file to a method in the main python file in the class here:
    class DesignerMainWindow(QtGui.QMainWindow, Ui_MainWindow):
        """Customization for Qt Designer created window"""
    
        signal_output_log = QtCore.Signal("QString")
        sig_clear_log = QtCore.Signal()
    
        def __init__(self, parent=None):
            super(DesignerMainWindow, self).__init__(parent)
            self.setupUi(self)
            self.image_analyzer = ImageAnalyzer(self)
            self.listener = watchdog_search.ObserverWrapper("/home/Test_Data/")
            self.on_finished_run(self.listener.wait_for_file())
        def on_finished_run(self, tuple: ()):
            self.image_analyzer.load_image(str(tuple[0]), str(tuple[1]), from_remote=True)
The .hdf5 file comes from this `watchdog_search.py:
    import time
    import traceback
    import os

    import h5py
    import queue
    from typing import Union

    from watchdog.observers import Observer
    from watchdog.events import FileSystemEventHandler, DirCreatedEvent, FileCreatedEvent


    class NewFileHandler(FileSystemEventHandler):
        """h5 file creation handler for Watchdog"""

        def __init__(self):
            self.file_queue = queue.Queue()

        # callback for File/Directory created event, called by Observer.
        def on_created(self, event: Union[DirCreatedEvent, FileCreatedEvent]):
            if event.src_path[-4:] == "hdf5":
                # run callback with path string
                self.file_queue.put(event.src_path)


    class ObserverWrapper:
        """Encapsulated Observer boilerplate"""

        def __init__(self, path: str, recursive=True):
            self.path = path
            self.recursive = recursive

            self.observer = Observer()
            self.handler = NewFileHandler()

            self.observer.schedule(self.handler, path=path, recursive=recursive)

            self.start()

        def start(self):
            """
            Starts observing for filesystem events. Runs self.routine() every 1 second.

            :param blocking: If true, blocks main thread until keyboard interrupt.
            """

            self.observer.start()
        def stop(self):
            """
            Stops the observer. When running self.start(blocking=True) then you don't need to call this.
            """

            self.observer.stop()
            self.observer.join()

        def wait_for_file(self):
            """
            Wait and Process newly created files
            """

            max_retry_count = 3500 # for test purposes now but want to set an upper bound on verifying a file is finished.
            # will try h5 file for a max of 35 seconds (upper bound) to see if the file is finished.
            # Files are usually finished within 20-30 seconds
            #
            retry_interval_seconds = .01 # every hundreth it will try the file to see if it finished writing

            # wait for file to be added
            #print(self.handler.file_queue.get(block=True))
            file_path = self.handler.file_queue.get(block=True)
            file_name = os.path.basename(file_path)

            # try to open the file
            retry_count = 0
            while True:
                try:
                    file = h5py.File(file_path, "r")
                    file.close()
                    return file_path, file_name
                except OSError:
                    if retry_count < max_retry_count:
                        retry_count += 1
                        print(f"h5 file <{file_path}> is locked, retrying {retry_count}/{max_retry_count}")
                        time.sleep(retry_interval_seconds)
                    else:
                        print(f"h5 file <{file_path}> reached max retry count, skipping")

                except Exception as err:
                    print(f"Got unexpected Error <{type(err).__name__}> while opening <{file_path}> ")
                    traceback.print_exc()
Currently I call this file by

    self.listener = watchdog_search.ObserverWrapper("/path/to/folder/of/interest")
in the main.py file but this only sends one hdf5 file and doesn't send any more. Watchdog needs to stay open and send content to main.py every time there is a new hdf5 file available. Does anyone know how to use Qt to do this? I was also thinking about using QTimer but I am not sure how this would work exactly. This is not a question of watchdog but rather a question of asynchronous programming and Qt. I need at the end to send the file_path and file_name of the .hdf5 to on_finished_run() or perhaps have on_finished_run() be the subscriber for the signal but I am unsure how to do this when the try returns not the emitted signal but rather the file path and name. Any insight is greatly appreciated.
Reply


Messages In This Thread
Using Qt to emit a signal (or maybe with QTimer) - by pyhill00 - Oct-06-2021, 01:15 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyQt] About QTimer and QThread and some general question catlessness 1 2,758 Nov-02-2021, 07:20 PM
Last Post: deanhystad
  [PyQt] QTimer not activating function after timeout LavaCreeperKing 0 3,906 Apr-03-2017, 09:09 PM
Last Post: LavaCreeperKing

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020