Using Qt to emit a signal in Python

I am trying to send a `.hdf5` file to a method in the main python file in the class here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
    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? 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.
Last edited on
> Any insight is greatly appreciated.
Yeah, post it on a Python forum.
Very insightful!
Hanske, Please move this thread to the lounge.
https://wiki.qt.io/Qt_for_Python_Signals_and_Slots

I can't see how this question has anything to do with signals and slots. However the reference shows how they work using Python.

The problem appears to relate to what happens within the slot internally/independently.
Registered users can post here. Sign in or register to post.