Каждый релиз приходится по тысячу раз проходить один и тот же сценарий? Чтобы добраться до новой фичи приходится нажимать одни и те же кнопки много раз? Хочется нажать на кнопку и чтобы все сделалось за тебя? Пора создать помощника, который облегчит рутину! Как? Ответ внутри.

В прошлый раз я рассказал об идее инструмента, который будет помогать в рутинных действиях и даже написали его в консольном варианте. Но что ни говори — не всегда это удобно. Пора приделать кнопки!

Вот так выглядит конечное окно с кнопками.

Тут все ограничивается только полетом фантазии и возможностями qt. Можно делать различные вкладки, переключалки, новые окна. Можно даже сделать свой собственный стиль окна.

Что там в коде?
Есть файл для старта нашего приложения, в моем случае тот же start.py, который мы потом и будем использовать как входную точку нашего приложения:
if __name__ == '__main__':
    app = QApplication(sys.argv)
    splash = Widgets.QSplashScreen(QtGui.QPixmap('splash_img.png'))

    splash.showMessage('Starting browser and application... ', Qt.AlignHCenter | Qt.AlignBottom, Qt.black)
    splash.show()
    app.processEvents()

    from app.main_window import MainWindow

    app.processEvents()
    window = MainWindow()
    app.processEvents()
    window.show()
    splash.finish(window)
    sys.exit(app.exec_())

Здесь появляется окно загрузки, которое висит, пока все не загрузится, а также загрузка браузера и основного окна

Создаем файл с нашим приложением, создаем там окно, выбираем размер и прочее. Вся эта информация есть в документации и уроках в интернете по pyqt 5, где вполне доступно все описано. Единственное, я использую *.ui файлы для интерфейса и теперь, чтобы добавить кнопку, мне нужно сделать так:

self.search.clicked.connect(lambda: self.start_thread(search))

Так же был подводный камень с тем, что если повесить на кнопку выполнение функции сценария, то пока функция выполняется и производит действия в запущенном браузере, главное окно зависает и некоторые ОС пытаются его убить. Решением стало увести выполнение функции в отдельный тред с помощью вспомогательного класса Worker:

import selenium
from PyQt5.QtCore import pyqtSignal, QObject


class Worker(QObject):
    finished = pyqtSignal()
    log = pyqtSignal(str)
    progress_bar = pyqtSignal(int)

    def __init__(self, progressBar, func, *func_args):
        super().__init__()
        self.progressBar = progressBar
        self.func = func
        self.func_args = func_args

    def work(self):
        try:
            self.func(self.progress_bar, *self.func_args)
        except (selenium.common.exceptions.TimeoutException, selenium.common.exceptions.WebDriverException) as e:
            self.log.emit('Message: {}.nPlease, try again or contact to developer'.format(e))

        self.finished.emit()

Здесь, кстати, я передаю переменную progress_bar и log, которые используются для заполнения полоски Прогресс бара и логирования всякой информации в главное окно.

def start_thread(self, func, *func_args):
    if self.t_finished:
        self.t_finished = False

        self.w = Worker(self.pbar, func, *func_args)
        self.w.finished.connect(self.on_finished)
        self.w.log[str].connect(self.log_with_html)
        self.w.progress_bar[int].connect(self.fill_bar)
        self.w.moveToThread(self.thread)
        self.thread.started.connect(self.w.work)
        self.thread.start()
    else:
        self.log_with_html('Process still working, please wait for ending')
 

Вот и сама функция, которая запускает тред после нажатия на кнопку в главном окне, и не дает нажать кнопку второй раз пока идет выполнение функции.

Сами сценарии тоже немного изменились, теперь в них вручную выставляется уровень прогресса:

def search(pbar):
    """Search with google"""
    pbar.emit(30)
    google.search('Funny cats')

Осталось запустить наше приложение обычным питоном:

python start.py

Весь исходный код можно посмотреть тут

Please follow and like us:
error

Оставить комментарий

avatar