Ответы пользователя по тегу PyQt
  • Изменение ProgressBar по итерациям в функции?

    Vindicar
    @Vindicar
    RTFM!
    Добавь функции ещё один параметр - callback-функцию, которая будет вызываться каждые X итераций.
    Тогда вопрос "как подружить функцию с индикацией прогресса" сведётся к написанию подходящей callback-функции. Условно:
    from time import sleep
    
    def worker(n: int, cb=None):
        for i in range(n):
            sleep(0.2)  # работу работаем
            if cb is not None and i % 5 == 0:
                cb(i, n)  # оповещаем, если пора и если есть что
        if cb is not None:
            cb(n, n)  # последнее оповещение на 100%. можно убрать
    
    # использование
    def callback(i, n):  # callback для вывода прогресса в консоль
        print(f'{i/n:.1%}')  # выводим процент  завершения
    
    worker(50, callback)  # работаем
    Ответ написан
    2 комментария
  • Не отображаются виджеты, приложение виснет, где ошибка?

    Vindicar
    @Vindicar
    RTFM!
    def setting(self):
        self.server.check_currency()
        ...
        self.setting()

    Что это за *непроизносимое марсианское ругательство*?
    Во-первых, ты реализуешь (вечный?) цикл через рекурсию, что само по себе глупо. Рекурсия куда более ограниченная штука, хотя бы из-за глубины стека.
    Во-вторых, у тебя именно что бесконечный цикл - ты не даёшь программе передышки, чтобы она могла отрисовать окно. По сути, у тебя выполнение зациклится намертво на строке window1 = Kurz(), так как приложение уйдёт в рекурсивный вызов self.setting() и из него уже не вернётся.

    Первая же ссылка в гугле по запросу "pyqt timer" даёт пример, как периодически обновлять содержимое окна, используя QTimer.

    Сначала читай, потом думай, потом уже бросайся делать.
    Ответ написан
    Комментировать
  • Как ускорить работу с большими таблицами данных?

    Vindicar
    @Vindicar
    RTFM!
    Я подозреваю, ты пытаешься на каждую строку данных создавать объект PyQT. Такого издевательства оно не переживёт.
    Вместо этого при прокрутке определи первую и последнюю видимую позицию в данных, очисти текущее содержимое своего окна с данными, и выведи только видимую часть данных.
    Ответ написан
    Комментировать
  • Как код с графическим интерфейсом на основе PyQt6 собрать в .exe?

    Vindicar
    @Vindicar
    RTFM!
    Плохо искал, раз не нашёл ни pyinstaller, ни GUI-обёртку для него auto-py-to-exe, .
    А если нашёл и не смог использовать, то про это и надо спрашивать.
    Ответ написан
  • Как навсегда изменить цвет кнопки при нажатии в Python?

    Vindicar
    @Vindicar
    RTFM!
    Свяжи обработчик событий с кнопкой.
    Заведи глобальную переменную, которая считает, сколько раз была нажата кнопка.
    В обработчике событий читай эту переменную, увеличь её на 1, в зависимости от значения вызывай self.pushButton.setStyleSheet() с разными стилями.
    Ответ написан
    1 комментарий
  • Почему сразу закрывается окно в PYQT?

    Vindicar
    @Vindicar
    RTFM!
    Во-первых, наверняка программа выводит сообщение об ошибке в консоль. Запусти её из терминала или IDE, чтобы этто сообщение увидеть.

    Во-вторых, я готов спорить что ты создаёшь QtWidgets.QApplication(sys.argv) не только в рамках create_reg_window(), но и в теле программы. А если я верно помню, в Qt приложении должен быть один и только один объект QApplication. Скорее всего, ошибка в этом. Так что гугли, как правильно делать приложение с несколькими окнами в Qt.
    Ответ написан
    1 комментарий
  • Как на python открыть содержимое pdf?

    Vindicar
    @Vindicar
    RTFM!
    По каким запросам гуглил? У меня вот "python render pdf to image" нашел пост, указывающий на pdf2image:
    from pdf2image import convert_from_path, convert_from_bytes
    # если у тебя есть именованный файл на диске
    images = convert_from_path('/home/belval/example.pdf')
    # или, если у тебя есть содержимое файла как объект bytes
    bytes_obj = open('/home/belval/example.pdf', 'rb').read()  # получаем объект bytes
    images = convert_from_bytes(bytes_obj)
    # так или иначе в images будет лежать список изображений PIL (пакет pillow), 
    # по одному на страницу. Их уже можно сохранять или делать с ними что-то ещё.

    Как вывести изображение PIL в GUI на PyQT - это уже второй вопрос.
    Ответ написан
    Комментировать
  • Возможно ли окно у окна отключить взаимодействие?

    Vindicar
    @Vindicar
    RTFM!
    Не знаю, есть ли решение через PyQT, но точно есть решение через WinAPI.
    SetWindowRgn() позволяет задать активный регион для окна. Точки, не входящие в этот регион, не будут обрабатываться ни при рисовании, ни при кликах.

    Пример

    import ctypes
    import ctypes.wintypes as w
    
    def ErrorIfZero(result, func, args):
        if not result:
            raise ctypes.WinError(ctypes.get_last_error())
        return result
    
    # используем user32.dll и kernel32.dll
    kernel32 = ctypes.windll.kernel32
    user32 = ctypes.windll.user32
    gdi32 = ctypes.windll.gdi32
    # описываем используемые функции, типы и константы 
    kernel32.GetConsoleWindow.argtypes = []
    kernel32.GetConsoleWindow.restype = w.HWND
    kernel32.GetConsoleWindow.check = ErrorIfZero
    
    user32.GetWindowRect.argtypes = [w.HWND, w.LPRECT]
    user32.GetWindowRect.restype = w.BOOL
    user32.GetWindowRect.check = ErrorIfZero
    
    user32.SetWindowRgn.argtypes = [w.HWND, w.HRGN, w.BOOL]
    user32.SetWindowRgn.restype = w.INT
    user32.SetWindowRgn.check = ErrorIfZero
    
    gdi32.DeleteObject.argtypes = [w.HANDLE]
    gdi32.DeleteObject.restype = w.BOOL
    gdi32.DeleteObject.check = ErrorIfZero
    
    gdi32.CreateRectRgnIndirect.argtypes = [w.LPRECT]
    gdi32.CreateRectRgnIndirect.restype = w.HRGN
    gdi32.CreateRectRgnIndirect.check = ErrorIfZero
    
    gdi32.CombineRgn.argtypes = [w.HRGN, w.HRGN, w.HRGN, w.INT]
    gdi32.CombineRgn.restype = w.INT
    gdi32.CombineRgn.check = ErrorIfZero
    RGN_AND  = 1
    RGN_OR   = 2
    RGN_XOR  = 3
    RGN_DIFF = 4
    RGN_COPY = 5
    
    
    hWnd = kernel32.GetConsoleWindow()
    r = w.RECT()
    user32.GetWindowRect(hWnd, ctypes.byref(r))
    r.left, r.right = 0, r.right - r.left
    r.top, r.bottom = -50, r.bottom - r.top #почему-то есть косяк с заголовком окна
    hole = w.RECT(r.right // 4, r.bottom // 4, 3 * r.right // 4, 3 * r.bottom // 4)
    
    hRgn = gdi32.CreateRectRgnIndirect(ctypes.byref(r))
    hHole = gdi32.CreateRectRgnIndirect(ctypes.byref(hole))
    gdi32.CombineRgn(hRgn, hRgn, hHole, RGN_DIFF)
    gdi32.DeleteObject(hHole)
    
    user32.SetWindowRgn(hWnd, hRgn, True)
    
    input('Press Enter to fix the hole.')
    
    user32.SetWindowRgn(hWnd, 0, True)
    gdi32.DeleteObject(hRgn)

    Ответ написан
    Комментировать
  • Как отобразить новый виджет после нажатия на пункт из меню?

    Vindicar
    @Vindicar
    RTFM!
    Я не работал с PyQT, но предложу догадку: ты создал новый объект QPixmap(), а как о нём узнает твоё окно, точнее, его родитель QMainWindow?
    Ответ написан
    Комментировать
  • Почему в .exe файле программы (Pyqt5) не исполняются команды к sqlite3?

    Vindicar
    @Vindicar
    RTFM!
    > Таблица это сама есть, базу данных я перебросил в корень с исполняемым файлом.
    Т.е. ты не пытаешься запаковать БД, так?
    А ты уверен, что скрипт её находит? Указываешь полный путь до файла с БД? Или как всегда, относительный, и авось текущая рабочая директория будет правильной?
    Просто некоторые py -> exe упаковщики при запуске экзешника распаковывают скрипт во временный каталог, и работают оттуда... а тогда файл БД окажется не рядом со скриптом. Не помню, делает ли так py2exe, выясни.
    Ответ написан
    7 комментариев
  • PyQT5. Открытие файла в textEdition в дочернем окне. Как реализовать?

    Vindicar
    @Vindicar
    RTFM!
    self.win = text.Ui_Text()

    Ты уверен, что при конструировании объекта окна автоматически вызовется его метод setupUi()?
    Ответ написан
    1 комментарий
  • Как сделать так, чтобы внутри одного виджета выполнялись разные действия?

    Vindicar
    @Vindicar
    RTFM!
    > кнопка брала директорию из первой кнопки
    И вот тут-то и косяк. Не из "первой кнопки", а из специально созданного (в __init__() разумеется) поля класса Convert_App. А записывать данные в это поле должен обработчик нажатия первой кнопки.
    Это азы питоновского ООП, освойте их и таких вопросов возникать не будет.
    Ответ написан
    Комментировать
  • Как можно скомпилировать файл конфигурации так, чтобы тело приложения загружало настройки?

    Vindicar
    @Vindicar
    RTFM!
    1. Определяешь формат файла конфигурации. Вариантов много:
    • простой ini-файл (модуль configparser) - удобен, если нужны мало-объемные данные, и не более двух уровней иерархии (т.е. группа-ключ со значением).
    • xml-файл (модуль xml) - громоздкий, но зато поддерживает много уровней вложенности и есть средства проверки корректности
    • json-файл (модуль json) - куда проще в плане синтаксиса, на выходе получаешь комбинацию из словарей и списков питона. Я бы посоветовал его.
    • Можно даже СУБД (типа sqlite3) прикрутить, при желании. Но это оправдано очень не всегда.

    2. Выбираешь место хранения конфига.
    • В папке программы? Будет одна конфигурация для всех пользователей на ПК. Не факт, что у тебя будут права на запись в эту папку. Зато легко копировать программу на другой комп.
    • В папке APPDATA пользователя? Далеко, пользователь вряд ли залезет, зато у разных пользователей на одном компе будут свои настройки. Сложнее перенести программу на другой комп - нужно будет еще найти и скопировать папку настроек. (Сложнее не в плане защиты от копирования, а в плане удобства распространения.)
    • В папке Мои документы пользователя? Не факт что это хорошая идея, но плюсы примерно те же что и выше.
    • Возможна комбинация предыдущих. Например, я делаю так: если в папке с исполняемым скриптом лежит файл с именем "portable", ищу конфиг тут же. Иначе ищу его в APPDATA.

    3. Определяешь, как будешь получать доступ к конфигу внутри программы. Например, отдельный модуль, который будут импортировать все части программы. Модуль содержит класс-синглтон, который содержит значения конфига в форме, удобной для остальной программы. Также этот класс может содержать значения конфигурации по умолчанию. Программа при старте ищет и загружает конфиг в экземпляр этого класса, при работе обращается к этому классу, чтобы получить или задать параметры, а при завершении - сохраняет класс обратно в конфиг.
    Ответ написан
    Комментировать
  • Питон выдает 'missing 1 required positional argument: 'self'', что делать?

    Vindicar
    @Vindicar
    RTFM!
    threadBeginCard = Timer(0.1, beginCard, args=None, kwargs=None)

    Я без понятия, что такое Timer(), но могу догадаться, что он делает.
    Он вызывает beginCard() без позиционных (args) или именованных (kwargs) параметров по наступлению некоторого события.
    Проблема в том, что ты вызываешь метод класса, т.е. фактически Class.beginCard(). Ему нужно первым параметром передать экземпляр класса, т.е. self.
    Если бы ты вызывал метод экземпляра, т.е.
    c = Class()
    c.beginCard()
    То тогда self был бы подставлен автоматически.

    Вывод: создать Timer() внутри экземплярного метода, и передать ему self.beginClass в качестве функции. Обрати внимание на отсутствие скобок.

    Правда, я фз что произойдёт дальше - вызов join() мне не очень нравится, так как он заблокирует поток UI до момента завершения рабочего потока.
    Ответ написан
  • QWidget: Must construct a QApplication before a QWidget?

    Vindicar
    @Vindicar
    RTFM!
    Ну чего, всё правильно пишет. Ты нигде не создаешь экземпляр класса QApplication, к которому должны цепляться все виджеты.
    Нагуглил бы hello world на PyQT5, сразу стало бы ясно.

    from PyQt5.QtWidgets import QApplication, QLabel
    app = QApplication([])
    
    # This is a requirement of Qt: Every GUI app must have exactly one instance of QApplication. 
    # Many parts of Qt don't work until you have executed the above line. 
    # You will therefore need it in virtually every (Py)Qt app you write.
    # The brackets [] in the above line represent the command line arguments passed to the application. 
    # Because our app doesn't use any parameters, we leave the brackets empty.
    label = QLabel('Hello World!')
    label.show()
    app.exec()
    Ответ написан
    2 комментария
  • Как вызвать self класса родителя?

    Vindicar
    @Vindicar
    RTFM!
    Неправильная терминология. Example - не родитель MyThread.
    Передайте ссылку на экземпляр Example (или на нужное поле) через параметр конструктора MyThread и сохраните её как экземплярную переменную класса MyThread. Но имейте ввиду - не факт, что вы сможете обратиться к элементам управления QT непосредственно из другого потока.
    Ответ написан
  • Написал на основе pydirectinput и pyqt5 простой антиафк, при нажатии кнопки запуск приложение вылетает, что делать?

    Vindicar
    @Vindicar
    RTFM!
    Приложение просто не отвечает после нажатия кнопки 'Запуск'(функция start)

    Ну а что, логично. Читай как устроены оконные приложения, это же азы рабоыт с любым GUI.
    Если кратко, у них в основе цикл, который принимает сообщения от ОС (нажата клавиша, сдвинута мышь, и т.д.) и обрабатывает их.
    PyQT реализует этот цикл сам, ты имеешь дело только с обработчиками событий - но цикл от этого никуда не девается. Всё происходит в одном потоке, так что пока обработчик события работает - цикл стоит, следующие сообщения ждут очереди.
    Так что когда ты делаешь while self.gag==True:, твой обработчик никогда не выйдет из цикла while, никогда не передаст управление оконному циклу, и щелчок по кнопке end никогда не будет обработан (кк и любое другое событие).

    Что делать?
    а) start запускает второй поток, end его останавливает. Кури документацию к модулю threading.
    б) смотри, есть ли в PyQt способ запланировать вызов функции на следующей итерации оконного цикла/спустя некоторое время. В этом случае ты можешь раз за разом планировать вызов своей функции, которая реализует одну итерацию (гапример, шлёт одно нажатие кнопки). Поскольку её вызов будет выполняться средствами оконного цикла, а отрабатывать она будет быстро, это не помешает оконному циклу.
    Ответ написан
    1 комментарий
  • Почему замерает окно приложения PyQt5?

    Vindicar
    @Vindicar
    RTFM!
    Потому что join() останавливает поток выполнения - в твоем случае поток GUI, который отвечает за работу окна приложения - пока целевой поток не завершится. Т.е. что ты делаешь - это эквивалент как если бы ты просто вызвал self.sucess_send_request(link, valid_proxy) прямо в обработчике события.

    Нужно дождаться завершения к какому моменту? К моменту закрытия окна? Или ещё к какому?
    Я бы сделал так: создай глобальные объекты (например, поля класса), доступные всем потокам. Один - типа threading.Lock, один - счётчик и один - типа threading.Event().
    Когда поток запускается, он захватывает Lock, увеличивает счётчик и сбрасывает Event (метод clear()), отпускает Lock.
    Когда поток готов завершиться, он захватывает Lock, уменьшает счётчик. Если после уменьшения счётчик стал равен 0, устанавливает Event (метод set()). Затем отпускает Lock. Убедись, что это происходит внутри try: finally:, чтобы непойманное исключение не сломало систему.

    Тогда главный поток приложения может просто время от времени проверять текущее значение счётчика (число активных потоков). А если надо, то может ждать на объекте Event, чтобы дождаться завершения всех потоков.
    Ответ написан
    3 комментария
  • Как получить результат и вывести его в другом окне?

    Vindicar
    @Vindicar
    RTFM!
    self.results = self.cursor.fetchall()
    self.output.setText(self.results)

    Я очень сомневаюсь, что label сумеет переварить список строк в качестве содержимого.
    Ответ написан
    Комментировать