diff --git a/PanACoTA/utils.py b/PanACoTA/utils.py
index 87db17ae603fb1ae4c7c136001ce16d791a40cd1..17f1e582048dd4d24cbe50930c1866079094034d 100755
--- a/PanACoTA/utils.py
+++ b/PanACoTA/utils.py
@@ -1303,3 +1303,24 @@ def remove(infile):
     """
     if os.path.isfile(infile):
         os.remove(infile)
+
+
+def thread_progressbar(widgets, stop):
+    """
+    Thread running an "inifite" progress bar, while the main thread is working.
+    Once this progressbar has to stop, we send a signal.
+
+    Parameters
+    ----------
+    widgets : list
+        list of widgets to put in the progressbar
+    stop : function
+        function returning False when thread can run, True when it has to stop.
+    """
+    if widgets:
+        bar = progressbar.ProgressBar(widgets=widgets, max_value=20, term_width=50)
+        while True:
+            bar.update()
+            if stop(): 
+                print()
+                break
diff --git a/test/test_unit/test_utils.py b/test/test_unit/test_utils.py
index 2884a81302092f776bc1d778aae4913c88069010..e30d2eb0afb5c3542232e31be633160649795279 100755
--- a/test/test_unit/test_utils.py
+++ b/test/test_unit/test_utils.py
@@ -12,6 +12,9 @@ import os
 import logging
 import shutil
 import matplotlib
+import progressbar
+import threading
+import time
 
 matplotlib.use('AGG')
 
@@ -1206,3 +1209,33 @@ def test_remove_not_exist():
     assert not os.path.isfile(infile)
     utils.remove(infile)
     assert not os.path.isfile(infile)
+
+
+def test_thread_progressbar(capsys):
+    """
+    Launch a progressbar in a separate thread, and stop it after 2 seconds
+    """
+    stop_bar = False
+    widgets = ['test', progressbar.BouncingBar(marker=progressbar.RotatingMarker(markers="◐◓◑◒")),
+                           "  -  ", progressbar.Timer()]
+    x = threading.Thread(target=utils.thread_progressbar, args=(widgets, lambda : stop_bar,))
+    x.start()
+    out, err = capsys.readouterr()
+    time.sleep(2)
+    stop_bar = True
+    x.join()
+
+
+def test_thread_empty_progressbar(capsys):
+    """
+    Launch a progressbar in a separate thread, and stop it after 2 seconds
+    as widgets is empty, the thread does not start anything, it ends just after being called.
+    """
+    stop_bar = False
+    widgets = []
+    x = threading.Thread(target=utils.thread_progressbar, args=(widgets, lambda : stop_bar,))
+    x.start()
+    out, err = capsys.readouterr()
+    time.sleep(0.5)
+    stop_bar = True
+    x.join()