Задать вопрос
Ответы пользователя по тегу PyQt
  • Почему не получается закрыть окно в PyQt5?

    Vindicar
    @Vindicar
    RTFM!
    Ну у твоего класса действительно есть только метод setupUi(), и нет метода close(). Неудивительно, что Питон этот метод тоже не находит.
    Я с Qt не знаком, поэтому поинтересуюсь: а MyMindow точно должно наследоваться от object? Может, от какого другого класса?

    А вообще выглядит всё так, словно этому коду место в MainWindow.
    Ответ написан
    Комментировать
  • Какую библитеку или интерфейс выбрать?

    Vindicar
    @Vindicar
    RTFM!
    Насчёт фреймворка не подскажу, а подскажу вот что: не нужно пытаться запихнуть всю безразмерную таблицу в GUI. Прокрутка - определение позиции - выборка данных, видимых на экране - рендеринг. Как-то так.
    Ответ написан
    2 комментария
  • Изменение 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 комментарий