Динамическое обновление таблицы информацией из базы данных MSSQL

Есть окно программы, в котором выводится таблица заполненная информацией находящийся в БД.

Каким способом можно сделать динамическое изменение таблицы, при изменении информации в БД. Как я понял, это делается по таймеру. То есть каждые n секунд мне надо вызывать testTableRequest().

Попробовал сделать по простому:

        self.conn = pyodbc.connect('Driver={SQL Server};'
                              'Server=LAPTOP-M6O5U927;'
                              'Database=testBD;'
                              'Trusted_Connection=yes;')
        while True:
            self.testTimer()

    def testTimer(self):
        self.testTableRequest()
        time.sleep(30)

    def testTableRequest(self):
        cursor = self.conn.cursor()
        request = 'SELECT * FROM testBD.dbo.firstTestTable'
        result = cursor.execute(request)

        labels = ['uid', 'name', 'value']
        self.tableWidget.setColumnCount(len(labels))
        self.tableWidget.setHorizontalHeaderLabels(labels)

        #self.tableWidget.verticalHeader().hide()

        self.array = []

        for row_number, row_data in enumerate(result):
            self.tableWidget.setRowCount(row_number+1)
            for col_number, data in enumerate(row_data):
                if col_number == 2:
                    self.array.append(data)
                self.tableWidget.setItem(row_number, col_number,QtWidgets.QTableWidgetItem(str(data)))
                    #print('value',row_number, col_number, data)
        self.plotTarget()

Но в таком случае зацикливается только на обновлении и окно программы не запускается.

Зашел почитать документацию и нашел там пример:

def hello():
    print("hello, world")

t = Timer(30.0, hello)
t.start()  # after 30 seconds, "hello, world" will be printed

В таком случае мне надо создать свой класс таймера и использовать его? Или где его найти?

Так же пробовал сделать через

    def testTimer(self):

        timer = threading.Timer(15.0, self.testTableRequest())
        timer.start()

Но в этом случае у меня просто постоянно обновлялись данные.


Ответы (2 шт):

Автор решения: RoyalGoose

Лучше всего вашу задачу можно решить с помощью стандартных библиотек schedule и time:

import schedule
import time
# тут ваша программа
if __name__ == "__main__": # если название файла не "main" тогда соотв. меняете тут и ниже название
    try:
        main()
        # здесь приведен пример обновления раз в минуту, но также вы можете использовать любые другие интервалы
        schedule.every().minute.do(main) 
        while True:
            schedule.run_pending()
            time.sleep(1)
    except Exception as ex: # здесь мы может захватывать ошибки, если необходимо
        print(ex)
        time.sleep(2)
→ Ссылка
Автор решения: S. Nick

Класс QTimer предоставляет повторяющиеся и одиночные таймеры.

QTimer::timeout() Этот сигнал испускается, когда таймер истекает.

Примечание: это частный сигнал. Он может использоваться в сигнальных соединениях, но не может излучаться пользователем.

Подробнее читаем здесь https://doc.qt.io/qt-5/qtimer.html#reimplemented-protected-functions

import sys
from PyQt5.QtCore    import QTimer, QDateTime
from PyQt5.QtWidgets import QWidget, QLabel, QVBoxLayout, QApplication, \
    QTextEdit, QPushButton


class MyGui(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.label = QLabel('time', self)
        self.textEdit = QTextEdit()
        self.button = QPushButton('Старт')
        self.button.clicked.connect(self.onButton)

        layout = QVBoxLayout(self)
        layout.addWidget(self.label)
        layout.addWidget(self.textEdit)
        layout.addWidget(self.button)

        self.timer = QTimer(self)
        self.timer.setInterval(1000)                  # интервал времени ожидания в миллисекундах
        self.timer.timeout.connect(self.displayTime)

    def displayTime(self):
        self.label.setText(QDateTime.currentDateTime().toString())
        self.textEdit.append('Hello World')

    def onButton(self):
        if self.button.text() == 'Старт':
            self.timer.start()                        # start
            self.button.setText('Стоп')
        else:
            self.timer.stop()                         # stop
            self.button.setText('Старт')           


if __name__ == "__main__":
    app = QApplication(sys.argv)
    gui = MyGui()
    gui.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка