8-900-374-94-44
[email protected]
Slide Image
Меню

Потоки qt: Qt/C++ — Урок 047. QThread

Содержание

используйте потоки Qt или потоки Python? Ru Python

Это было обсуждено не так давно в списке рассылки PyQt. Цитируя комментарии Джованни Баджо на эту тему:

Это в основном то же самое. Основное отличие состоит в том, что QThreads лучше интегрированы с Qt (асинхронные сигналы / слоты, цикл событий и т. Д.). Кроме того, вы не можете использовать Qt из потока Python (вы не можете, например, отправить событие в основной поток через QApplication.postEvent): для работы вам нужен QThread.

Общее правило может заключаться в использовании QThreads, если вы собираетесь каким-то образом взаимодействовать с Qt и использовать потоки Python в противном случае.

И некоторые более ранние комментарии по этому вопросу от автора PyQt: «они оба обертки вокруг тех же реализаций собственных потоков». И обе реализации используют GIL таким же образом.

Нити Python будут проще и безопаснее, и поскольку они предназначены для приложения на основе ввода-вывода, они могут обойти GIL.

Тем не менее, рассматривали ли вы неблокирующий ввод-вывод с использованием витых или неблокирующих сокетов / select?

EDIT: больше по потокам

Нити Python

Потоки Python – это системные потоки. Тем не менее, Python использует глобальную блокировку интерпретатора (GIL), чтобы гарантировать, что интерпретатор выполняет только определенный блок размера инструкций байтового кода за раз. К счастью, Python выпускает GIL во время операций ввода-вывода, делая потоки полезными для имитации неблокирующего ввода-вывода.

Важное предупреждение: это может ввести в заблуждение, так как количество инструкций байт-кода не соответствует количеству строк в программе. Даже одно назначение не может быть атомарным в Python, поэтому блокировка мьютекса необходима для любого блока кода, который должен выполняться атомарно, даже с GIL.

Потоки QT

Когда Python отключает управление сторонним компилированным модулем, он выпускает GIL. В обязанности модуля входит обеспечение атомарности, когда это необходимо. Когда управление передается обратно, Python будет использовать GIL. Это может сделать использование сторонних библиотек в связи с запутанностью потоков. Еще сложнее использовать внешнюю библиотеку потоков, поскольку она добавляет неопределенность относительно того, где и когда управление находится в руках модуля и интерпретатора.

Потоки QT работают с выпущенным GIL. Потоки QT могут выполнять код библиотеки QT (и другой код скомпилированного модуля, который не получает GIL) одновременно. Тем не менее, код Python, выполняемый в контексте потока QT, по- прежнему приобретает GIL, и теперь вам нужно управлять двумя наборами логики для блокировки вашего кода.

В конце концов, как потоки QT, так и потоки Python являются обертками вокруг потоков системы. Потоки Python являются более безопасными для использования, поскольку те части, которые не написаны на Python (неявно использующие GIL), используют GIL в любом случае (хотя вышеописанное предостережение применяется).

Неблокирующий ввод-вывод

Темы добавляют необычайную сложность вашему приложению. Особенно при работе с уже сложным взаимодействием между интерпретатором Python и скомпилированным модульным кодом. В то время как многие находят, что программирование на основе событий сложно отслеживать, неблокирующий ввод-вывод, основанный на событиях, часто гораздо менее сложно рассуждать, чем потоки.

С асинхронным вводом-выводом вы всегда можете быть уверены, что для каждого открытого дескриптора путь выполнения согласован и упорядочен. Есть, очевидно, проблемы, которые необходимо решить, например, что делать, когда код, зависящий от одного открытого канала, зависит от результатов кода, который будет вызываться, когда другой открытый канал возвращает данные.

Одним из прекрасных решений для ввода-вывода без событий, основанных на событиях, является новая библиотека Diesel . На данный момент он ограничен Linux, но он необычайно быстрый и довольно элегантный.

Также стоит потратить время на изучение pyevent , обертки вокруг замечательной библиотеки libevent, которая обеспечивает базовую основу для программирования на основе событий, используя самый быстрый доступный для вашей системы метод (определенный во время компиляции).

Я задал себе тот же вопрос, когда работал над PyTalk .

Если вы используете Qt, вам нужно использовать QThread чтобы иметь возможность использовать структуру Qt и, в первую очередь, систему сигналов / слотов.

С движком сигнала / слота вы сможете разговаривать из потока в другой и с каждой частью вашего проекта.

Более того, вопрос об этом выборе очень невелик, так как оба являются связями C ++.

Вот мой опыт PyQt и потока.

Я рекомендую вам использовать QThread .

Я тоже не могу рекомендовать, но я могу попытаться описать различия между потоками CPython и Qt.

Прежде всего, потоки CPython не запускаются одновременно, по крайней мере, не с кодом Python. Да, они создают системные потоки для каждого потока Python, однако разрешен запуск только потока, в котором сейчас выполняется Global Interpreter Lock (расширения C и код FFI могут обходить его, но байт-код Python не выполняется, пока поток не содержит GIL).

С другой стороны, у нас есть потоки Qt, которые в основном являются общими для системных потоков, не имеют Global Interpreter Lock и, таким образом, могут работать одновременно. Я не уверен, как PyQt справляется с этим, однако, если ваши потоки Qt не назовут код Python, они должны иметь возможность запускать одновременно (блокировать различные дополнительные блокировки, которые могут быть реализованы в различных структурах).

Для дополнительной тонкой настройки вы можете изменить количество инструкций байт-кода, которые интерпретируются перед переключением права собственности на GIL – более низкие значения означают большее переключение контекста (и, возможно, более высокую отзывчивость), но более низкую производительность для каждого потока (коммутаторы контекста имеют свою стоимость – если вы попробуйте переключить каждые несколько инструкций, это не ускорит скорость. )

Надеюсь, что это поможет с вашими проблемами 🙂

использовать потоки Qt или потоки Python?

Потоки Python будут проще и безопаснее, и, поскольку они предназначены для приложений на основе ввода-вывода, они могут обходить GIL. Тем не менее, рассматривали ли вы неблокирующий ввод-вывод с использованием Twisted или неблокирующих сокетов / select?

РЕДАКТИРОВАТЬ: подробнее о потоках

Потоки Python

Потоки Python — это системные потоки. Однако Python использует глобальную блокировку интерпретатора (GIL), чтобы гарантировать, что интерпретатор одновременно выполняет только блок инструкций байтового кода определенного размера. К счастью, Python выпускает GIL во время операций ввода / вывода, делая потоки полезными для моделирования неблокирующего ввода / вывода.

Важное предупреждение: это может ввести в заблуждение, поскольку количество инструкций байт-кода не соответствует количеству строк в программе.

Даже одно присвоение не может быть атомарным в Python, поэтому блокировка мьютекса необходима для любого блока кода, который должен выполняться атомарно, даже с GIL.

QT потоки

Когда Python передает управление стороннему скомпилированному модулю, он освобождает GIL. Ответственность за обеспечение атомарности там, где это необходимо, ложится на модуль. Когда управление будет передано обратно, Python будет использовать GIL. Это может сбивать с толку использование сторонних библиотек в сочетании с потоками. Еще сложнее использовать внешнюю библиотеку потоков, потому что это добавляет неопределенности относительно того, где и когда управление находится в руках модуля, а не интерпретатора.

Потоки QT работают с выпущенным GIL. Потоки QT могут выполнять код библиотеки QT (и другой код скомпилированного модуля, который не получает GIL) одновременно. Однако код Python, выполняемый в контексте потока QT, по- прежнему получает GIL, и теперь вам нужно управлять

двумя наборами логики для блокировки вашего кода.

В конце концов, и потоки QT, и потоки Python являются оболочкой для системных потоков. Потоки Python немного безопаснее использовать, поскольку те части, которые написаны не на Python (неявно с использованием GIL), в любом случае используют GIL (хотя приведенное выше предостережение все еще применяется).

Неблокирующий ввод / вывод

Потоки чрезвычайно усложняют ваше приложение. Особенно при и без того сложном взаимодействии интерпретатора Python и скомпилированного кода модуля. Хотя многим сложно следовать программированию на основе событий, неблокирующий ввод-вывод, основанный на событиях, зачастую гораздо труднее рассуждать, чем потоки.

С асинхронным вводом-выводом вы всегда можете быть уверены, что для каждого открытого дескриптора путь выполнения согласован и упорядочен. Очевидно, есть проблемы, которые необходимо решить, например, что делать, когда код, зависящий от одного открытого канала, в дальнейшем зависит от результатов кода, который будет вызываться, когда другой открытый канал возвращает данные.

Хорошим решением для событийного неблокирующего ввода-вывода является новая библиотека Diesel . На данный момент он ограничен Linux, но он необычайно быстр и довольно элегантен.

Также стоит потратить время на изучение pyevent , оболочки для замечательной библиотеки libevent, которая обеспечивает базовую структуру для программирования на основе событий с использованием самого быстрого доступного метода для вашей системы (определяется во время компиляции).

python — Потоки в приложении PyQt: Использовать потоки Qt или потоки Python?

Я пишу приложение с графическим интерфейсом, которое регулярно получает данные через веб-соединение. Так как этот поиск занимает некоторое время, это приводит к тому, что пользовательский интерфейс перестает отвечать на запросы в процессе поиска (его нельзя разбить на более мелкие части). Вот почему я хотел бы передать веб-соединение в отдельный рабочий поток.

[Да, я знаю, сейчас у меня две проблемы а> . ]

В любом случае, приложение использует PyQt4, поэтому я хотел бы знать, какой вариант лучше: использовать потоки Qt или использовать модуль Python threading? Каковы преимущества / недостатки каждого? Или у тебя совершенно другое предложение?

Изменить (re bounty). Хотя в моем конкретном случае решение, вероятно, будет использовать неблокирующий сетевой запрос, например Джефф Обер и предложил Лукаш Лалинский (так что, в сущности, оставляя проблемы с параллелизмом для сетевой реализации), я бы по-прежнему как более глубокий ответ на общий вопрос:

Каковы преимущества и недостатки использования потоков PyQt4 (т.е. Qt) по сравнению с собственными потоками Python (из модуля threading)?


Изменить 2 . Спасибо всем за ответы. Хотя не существует 100% -ого согласия, похоже, что существует широко распространенное мнение, что ответом является «использовать Qt», поскольку его преимущество заключается в интеграции с остальной частью библиотеки, не вызывая при этом реальных недостатков.

Для тех, кто хочет выбрать между двумя реализациями потоков, я настоятельно рекомендую прочитать все ответы, представленные здесь, включая ветку списка рассылки PyQt, которая abbot ссылается на.

Было несколько ответов, которые я рассмотрел для награды; в конце концов я выбрал настоятеля для очень релевантной внешней ссылки; это был, однако, близкий звонок.

Еще раз спасибо.

120

balpha 20 Окт 2009 в 19:54

7 ответов

Лучший ответ

Это обсуждалось не так давно в списке рассылки PyQt. Цитируя комментарии Джованни Баджо на эту тему:

Это в основном то же самое. Основное отличие состоит в том, что QThreads лучше интегрированы с Qt (асинхронные сигналы / слоты, цикл обработки событий и т. Д.). Кроме того, вы не можете использовать Qt из потока Python (например, вы не можете публиковать события в главном потоке через QApplication. postEvent): вам нужен QThread, чтобы это работало.

Общее практическое правило может заключаться в использовании QThreads, если вы собираетесь каким-либо образом взаимодействовать с Qt, и в противном случае использовать потоки Python.

И некоторые ранее прокомментировали эту тему от автора PyQt: «они оба являются обертками вокруг одних и тех же собственных реализаций потоков». И обе реализации используют GIL одинаково.

110

abbot 3 Апр 2012 в 15:33

Я не могу прокомментировать точные различия между потоками Python и PyQt, но я делал то, что вы пытаетесь сделать, используя QThread, QNetworkAcessManager и проверяя, чтобы вызвать QApplication.processEvents() пока нить жива. Если реакция GUI действительно является проблемой, которую вы пытаетесь решить, позже поможет.

0

brianz 25 Окт 2009 в 05:24

Я тоже не могу рекомендовать, но я могу попытаться описать различия между потоками CPython и Qt.

Прежде всего, потоки CPython не работают одновременно, по крайней мере, не код Python. Да, они создают системные потоки для каждого потока Python, однако разрешено запускать только поток, в настоящее время содержащий глобальную блокировку интерпретатора (расширения C и код FFI могут его обойти, но байт-код Python не выполняется, пока поток не содержит GIL).

С другой стороны, у нас есть потоки Qt, которые по сути являются общим слоем над системными потоками, не имеют глобальной блокировки интерпретатора и, следовательно, способны работать одновременно. Я не уверен, как PyQt справляется с этим, однако, если ваши потоки Qt не вызывают код Python, они должны быть в состоянии работать одновременно (за исключением различных дополнительных блокировок, которые могут быть реализованы в различных структурах).

Для дополнительной тонкой настройки вы можете изменить количество инструкций байт-кода, которые интерпретируются перед переключением владельца GIL — более низкие значения означают большее переключение контекста (и, возможно, более высокую скорость отклика), но более низкую производительность для отдельного потока (переключатели контекста имеют свою стоимость — если вы попробуйте переключать каждые несколько инструкций, это не помогает скорости.)

Надеюсь, это поможет с вашими проблемами 🙂

5

p_l 28 Окт 2009 в 09:15

У Джеффа есть несколько хороших моментов. Только один основной поток может выполнять любые обновления графического интерфейса. Если вам нужно обновить графический интерфейс из потока, Qt-4 сигналы подключения в очереди упрощают отправку данных между потоками и будут автоматически вызываться, если вы используете QThread; Я не уверен, будут ли они, если вы используете потоки Python, хотя добавить параметр в connect() легко.

9

ekhumoro 19 Янв 2017 в 17:29

Я задавал себе тот же вопрос, когда работал над PyTalk.

Если вы используете Qt, вам нужно использовать QThread, чтобы иметь возможность использовать каркас Qt и особенно систему сигналов / слотов.

С помощью механизма сигналов / слотов вы сможете общаться из одного потока в другой и с каждой частью вашего проекта.

Более того, вопрос об этом выборе не очень высок, поскольку оба являются привязками C ++.

Вот мой опыт PyQt и потока.

Я рекомендую вам использовать QThread.

14

Natim 27 Окт 2009 в 01:17

Преимущество QThread заключается в том, что он интегрирован с остальной частью библиотеки Qt. То есть методы с поддержкой потоков в Qt должны будут знать, в каком потоке они работают, и для перемещения объектов между потоками вам нужно будет использовать QThread. Еще одна полезная функция — запуск собственного цикла событий в потоке.

Если вы обращаетесь к HTTP-серверу, вы должны рассмотреть QNetworkAccessManager.

21

Lukáš Lalinský 20 Окт 2009 в 16:11

Потоки Python будут проще и безопаснее, и, поскольку они предназначены для приложений на основе ввода / вывода, они могут обходить GIL. Тем не менее, вы рассматривали неблокирующие операции ввода-вывода с использованием витых или неблокирующих сокетов / select?

РЕДАКТИРОВАТЬ: больше о темах

Темы Python

Потоки Python — это системные потоки. Однако Python использует глобальную блокировку интерпретатора (GIL), чтобы гарантировать, что интерпретатор только когда-либо выполняет блок байтового кода определенного размера за раз. К счастью, Python освобождает GIL во время операций ввода / вывода, что делает потоки полезными для имитации неблокирующего ввода / вывода.

Важное предупреждение: Это может вводить в заблуждение, поскольку число инструкций байт-кода не соответствует количеству строк в программе. Даже одно назначение не может быть атомарным в Python, поэтому блокировка мьютекса необходима для любого блока кода, который должен выполняться атомарно, даже с GIL.

Темы QT

Когда Python передает управление стороннему скомпилированному модулю, он освобождает GIL. Модуль несет ответственность за обеспечение атомарности, где это необходимо. Когда управление передается обратно, Python будет использовать GIL. Это может затруднить использование сторонних библиотек в сочетании с потоками. Еще сложнее использовать внешнюю библиотеку потоков, поскольку она добавляет неопределенность относительно того, где и когда управление находится в руках модуля против интерпретатора.

Потоки QT работают с освобожденным GIL. Потоки QT могут выполнять код библиотеки QT (и другой код скомпилированного модуля, который не получает GIL) одновременно. Однако код Python, выполняемый в контексте потока QT still , получает GIL, и теперь вам нужно управлять двумя наборами логики для блокировки вашего кода.

В конце и потоки QT, и потоки Python являются обертками вокруг системных потоков. Потоки Python немного безопаснее в использовании, поскольку те части, которые не написаны на Python (неявно используют GIL), в любом случае используют GIL (хотя оговорка выше все еще применима).

Неблокирующий ввод / вывод

Потоки чрезвычайно усложняют ваше приложение. Особенно, когда речь идет о и без того сложном взаимодействии между интерпретатором Python и скомпилированным модульным кодом. В то время как многим трудно следовать программированию на основе событий, неблокирующий ввод-вывод на основе событий зачастую гораздо менее труден для рассуждения, чем потоки.

Благодаря асинхронному вводу-выводу вы всегда можете быть уверены, что для каждого открытого дескриптора путь выполнения является согласованным и упорядоченным. Очевидно, есть проблемы, которые необходимо решить, например, что делать, когда код, зависящий от одного открытого канала, далее зависит от результатов кода, вызываемого, когда другой открытый канал возвращает данные.

Хорошим решением для неблокирующего ввода-вывода на основе событий является новая дизельная библиотека. На данный момент он ограничен Linux, но он чрезвычайно быстрый и довольно элегантный.

Также стоит потратить время на изучение pyevent — обертки вокруг замечательной библиотеки libevent, которая предоставляет базовая основа для программирования на основе событий с использованием самого быстрого метода, доступного для вашей системы (определяется во время компиляции).

34

Jeff Ober 29 Окт 2009 в 11:52

Класс QMediaStreamsControl | Qt Мультимедиа 5.

15.4

Класс QMediaStreamsControl предоставляет элемент управления выбором медиапотока. Подробнее …

Заголовок: #include
qmake: QT + = multimedia
Наследует: QMediaControl

Этот класс устарел. Он предназначен для сохранения работоспособности старого исходного кода. Мы настоятельно не рекомендуем использовать его в новом коде.

Открытые типы

перечисление StreamType {AudioStream, VideoStream, SubPictureStream, UnknownStream, DataStream}

Открытые функции

Сигналы

Защищенные функции

Макросы

Подробное описание

Класс QMediaStreamsControl предоставляет описания доступных медиапотоков и позволяет активировать и деактивировать отдельные потоки.

Имя интерфейса QMediaStreamsControl — org. qt-project.qt.mediastreamscontrol / 5.0 , как определено в QMediaStreamsControl_iid.

См. Также QMediaService :: requestControl ().

Документация по типу элемента

Перечисление

QMediaStreamsControl :: StreamType

Тип медиапотока.

Константа Значение Описание
QMediaStreamsControl :: AudioStream 2 Аудиопоток.
QMediaStreamsControl :: VideoStream 1 Видеопоток.
QMediaStreamsControl :: SubPictureStream 3 Поток фрагмента изображения или телетекста.
QMediaStreamsControl :: UnknownStream 0 Тип потока неизвестен.
QMediaStreamsControl :: DataStream 4

Документация по функциям-членам

[защищенный] QMediaStreamsControl :: QMediaStreamsControl (родительский объект QObject * = nullptr)

Создает новый элемент управления потоками мультимедиа с заданным родительским элементом .

[сигнал] void QMediaStreamsControl :: activeStreamsChanged ()

Сигнал излучается при изменении списка активных потоков.

[сигнал] void QMediaStreamsControl :: streamsChanged ()

Сигнал излучается при изменении списка доступных потоков.

[виртуальный] QMediaStreamsControl :: ~ QMediaStreamsControl ()

Уничтожает элемент управления медиа-потоками.

[чисто виртуальный] bool QMediaStreamsControl :: isActive (int streamNumber )

Возвращает истину, если медиапоток streamNumber активен.

[чисто виртуальный] QVariant QMediaStreamsControl :: metaData (int streamNumber , const QString & key )

Возвращает значение метаданных ключа для данного streamNumber .

Полезные ключи метаданных: QMediaMetaData :: Title, QMediaMetaData :: Description и QMediaMetaData :: Language.

[чисто виртуальный] void QMediaStreamsControl :: setActive (int streamNumber , bool state )

Устанавливает активное состояние медиапотока streamNumber .

Установка для активного состояния медиапотока значения true активирует его. Если ранее был активен какой-либо другой поток того же типа, он будет деактивирован. Установка активного состояния медиапотока на false деактивирует его.

См. Также isActive ().

[чисто виртуальный] int QMediaStreamsControl :: streamCount ()

Возвращает количество медиапотоков.

[чисто виртуальный] QMediaStreamsControl :: StreamType QMediaStreamsControl :: streamType (int streamNumber )

Вернуть тип медиапотока streamNumber .

Макро-документация

QMediaStreamsControl_iid

org.qt-project.qt.mediastreamscontrol / 5.0

Определяет имя интерфейса класса QMediaStreamsControl.

© 2021 Компания Qt Company Ltd. Вклад в документацию, включенный в этот документ, является собственностью их владельцы. Представленная здесь документация лицензирована в соответствии с условиями лицензии GNU Free Documentation License версии 1.3, опубликованной Free Software Foundation.Qt и соответствующие логотипы являются товарными знаками компании Qt Company Ltd. в Финляндии и / или других странах по всему миру. Все остальные товарные знаки являются собственностью их владельцев.

Класс QFileDevice | Qt Core 5.15.4

Класс QFileDevice предоставляет интерфейс для чтения и записи в открытые файлы. Подробнее …

Этот класс был представлен в Qt 5.0.

Документация по типу элемента

перечисление QFileDevice :: FileError

Это перечисление описывает ошибки, которые могут быть возвращены функцией error ().

Константа Значение Описание
QFileDevice :: NoError 0 Ошибка не возникла.
QFileDevice :: ReadError 1 Произошла ошибка при чтении из файла.
QFileDevice :: WriteError 2 Произошла ошибка при записи в файл.
QFileDevice :: FatalError 3 Произошла фатальная ошибка.
QFileDevice :: ResourceError 4 Недостаточно ресурсов (например, слишком много открытых файлов, нехватка памяти и т. Д.)
QFileDevice :: OpenError 5 Не удалось открыть файл.
QFileDevice :: AbortError 6 Операция была прервана.
QFileDevice :: TimeOutError 7 Истекло время ожидания.
QFileDevice :: UnspecifiedError 8 Произошла неопределенная ошибка.
QFileDevice :: RemoveError 9 Не удалось удалить файл.
QFileDevice :: RenameError 10 Не удалось переименовать файл.
QFileDevice :: PositionError 11 Позиция в файле не может быть изменена.
QFileDevice :: ResizeError 12 Не удалось изменить размер файла.
QFileDevice :: PermissionsError 13 Нет доступа к файлу.
QFileDevice :: CopyError 14 Не удалось скопировать файл.

перечисление QFileDevice :: FileHandleFlag


flags QFileDevice :: FileHandleFlags

Это перечисление используется при открытии файла для указания дополнительных параметров, которые применяются только к файлам, а не к общему QIODevice.

Константа Значение Описание
QFileDevice :: AutoCloseHandle 0x0001 Дескриптор файла, переданный в open (), должен быть закрыт с помощью close (), поведение по умолчанию таково, что закрытие просто сбрасывает файл, и приложение отвечает за закрытие дескриптора файла.При открытии файла по имени этот флаг игнорируется, поскольку Qt всегда владеет дескриптором файла и должна его закрыть.
QFileDevice :: DontCloseHandle 0 Если не закрыто явно, базовый дескриптор файла остается открытым при уничтожении объекта QFile.

Тип FileHandleFlags - это typedef для QFlags . Он хранит комбинацию значений FileHandleFlag по ИЛИ.

перечисление QFileDevice :: FileTime

Это перечисление используется функциями fileTime () и setFileTime ().

Константа Значение Описание
QFileDevice :: FileAccessTime 0 Время последнего обращения к файлу (например, чтение или запись).
QFileDevice :: FileBirthTime 1 Время создания файла (может не поддерживаться в UNIX).
QFileDevice :: FileMetadataChangeTime 2 Время последнего изменения метаданных файла.
QFileDevice :: FileModificationTime 3 Время последнего изменения файла.

Это перечисление было введено или изменено в Qt 5.10.

См. Также setFileTime (), fileTime () и QFileInfo :: fileTime ().

Перечисление

QFileDevice :: MemoryMapFlags

Это перечисление описывает специальные параметры, которые могут использоваться функцией map ().

Константа Значение Описание
QFileDevice :: NoOptions 0 Без опций.
QFileDevice :: MapPrivateOption 0x0001 Отображаемая память будет частной, поэтому любые изменения не будут видны другим процессам и не будут записаны на диск. Любые такие модификации будут потеряны, когда память не будет отображена. Не указано, будут ли изменения, внесенные в файл, сделанные после создания сопоставления, видны через отображаемую память. Это значение перечисления было введено в Qt 5.4.

Это перечисление было введено или изменено в Qt 4.4.

перечисление QFileDevice :: Permission


flags QFileDevice :: Permissions

Это перечисление используется функцией permission () для сообщения о разрешениях и владении файлом. Значения могут быть объединены оператором ИЛИ для проверки нескольких значений разрешений и владения.

Константа Значение Описание
QFileDevice :: ReadOwner 0x4000 Файл доступен для чтения владельцем файла.
QFileDevice :: WriteOwner 0x2000 Файл доступен для записи владельцем файла.
QFileDevice :: ExeOwner 0x1000 Файл является исполняемым владельцем файла.
QFileDevice :: ReadUser 0x0400 Пользователь может читать файл.
QFileDevice :: WriteUser 0x0200 Пользователь доступен для записи.
QFileDevice :: ExeUser 0x0100 Пользователь может исполнять файл.
QFileDevice :: ReadGroup 0x0040 Файл доступен для чтения группой.
QFileDevice :: WriteGroup 0x0020 Группа доступна для записи в файл.
QFileDevice :: ExeGroup 0x0010 Файл может исполняться группой.
QFileDevice :: ReadOther 0x0004 Файл доступен для чтения всем.
QFileDevice :: WriteOther 0x0002 Файл доступен для записи любому пользователю.
QFileDevice :: ExeOther 0x0001 Файл может быть выполнен кем угодно.

Предупреждение: Из-за различий в платформах, поддерживаемых Qt, семантика ReadUser, WriteUser и ExeUser зависит от платформы: в Unix возвращаются права владельца файла, а в Windows - права текущего пользователя. возвращаются.Это поведение может измениться в будущей версии Qt.

Примечание: В файловых системах NTFS проверка прав собственности и разрешений по умолчанию отключена из соображений производительности. Чтобы включить его, включите следующую строку:

 внешний Q_CORE_EXPORT int qt_ntfs_permission_lookup; 

Проверка разрешений затем включается и выключается путем увеличения и уменьшения qt_ntfs_permission_lookup на 1.

 qt_ntfs_permission_lookup ++;
qt_ntfs_permission_lookup--; 

Тип разрешений - это typedef для QFlags .Он хранит комбинацию значений разрешений по ИЛИ.

Документация по функциям-членам

[виртуальный] QFileDevice :: ~ QFileDevice ()

Уничтожает файловое устройство, при необходимости закрывая его.

[переопределить виртуальный] bool QFileDevice :: atEnd () const

Переопределения: QIODevice :: atEnd () const.

Возвращает true , если достигнут конец файла; в противном случае возвращает false.

Для обычных пустых файлов в Unix (например,грамм. те, что в / proc ), эта функция возвращает true , поскольку файловая система сообщает, что размер такого файла равен 0. Следовательно, вы не должны зависеть от atEnd () при чтении данных из такого файла, а скорее вызывайте read () до тех пор, пока не перестанут считываться данные.

[переопределить виртуальный] void QFileDevice :: close ()

Переопределения: QIODevice :: close ().

Вызывает QFileDevice :: flush () и закрывает файл. Ошибки сброса игнорируются.

См. Также QIODevice :: close ().

QFileDevice :: FileError QFileDevice :: error () const

Возвращает состояние ошибки файла.

Состояние устройства ввода-вывода возвращает код ошибки. Например, если open () возвращает false или операция чтения / записи возвращает -1, эту функцию можно вызвать, чтобы выяснить причину сбоя операции.

См. Также unsetError ().

[виртуальный] QString QFileDevice :: fileName () const

Возвращает имя файла.Реализация по умолчанию в QFileDevice возвращает пустую строку.

QDateTime QFileDevice :: fileTime (QFileDevice :: FileTime

время ) const

Возвращает время файла, указанное время . Если время не может быть определено, верните QDateTime () (недопустимая дата и время).

Эта функция была представлена ​​в Qt 5.10.

См. Также setFileTime (), FileTime и QDateTime :: isValid ().

bool QFileDevice :: flush ()

Сбрасывает все буферизованные данные в файл.В случае успеха возвращает true ; в противном случае возвращает false .

int QFileDevice :: handle () const

Возвращает дескриптор файла.

Это небольшое положительное целое число, подходящее для использования с функциями библиотеки C, такими как fdopen () и fcntl () . В системах, которые используют файловые дескрипторы для сокетов (например, системы Unix, но не Windows), дескриптор также может использоваться с QSocketNotifier.

Если файл не открыт или произошла ошибка, handle () возвращает -1.

См. Также QSocketNotifier.

[переопределить виртуальный] bool QFileDevice :: isSequential () const

Переопределения: QIODevice :: isSequential () const.

Возвращает true , если с файлом можно работать только последовательно; в противном случае возвращает false .

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

См. Также QIODevice :: isSequential ().

uchar * QFileDevice :: map (qint64

смещение , qint64 размер , QFileDevice :: MemoryMapFlags flags = NoOptions)

Отображает размером байта файла в память, начиная со смещения .Файл должен быть открыт для успешного сопоставления, но файл не обязательно должен оставаться открытым после сопоставления памяти. Когда QFile уничтожается или открывается новый файл с этим объектом, любые карты, которые не были отображены, автоматически отключаются.

Отображение будет иметь тот же открытый режим, что и файл (чтение и / или запись), за исключением случаев использования MapPrivateOption, и в этом случае всегда возможна запись в отображаемую память.

Любые параметры отображения могут быть переданы через флагов .

Возвращает указатель на память или nullptr в случае ошибки.

См. Также unmap ().

[виртуальный] QFileDevice :: Permissions QFileDevice :: permissions () const

Возвращает полную комбинацию OR-ed вместе QFile :: Permission для файла.

См. Также setPermissions ().

[переопределить виртуальный] qint64 QFileDevice :: pos () const

Переопределения: QIODevice :: pos () const.

[переопределить виртуальную защиту] qint64 QFileDevice :: readData (char * data , qint64 len )

Переопределения: QIODevice :: readData (char * data, qint64 maxSize).

[переопределить виртуальную защиту] qint64 QFileDevice :: readLineData (char * data , qint64 maxlen )

Переопределения: QIODevice :: readLineData (char * data, qint64 maxSize).

[виртуальный] bool QFileDevice :: resize (qint64 sz )

Устанавливает размер файла (в байтах) sz .Возвращает true , если изменение размера выполнено успешно; в противном случае - ложь. Если sz больше, чем текущий файл, новые байты будут установлены в 0; если sz меньше, файл просто обрезается.

Предупреждение: Эта функция может завершиться ошибкой, если файл не существует.

См. Также размер ().

[переопределить виртуальный] bool QFileDevice :: seek (qint64 pos )

Переопределения: QIODevice :: seek (qint64 pos).

Для устройств с произвольным доступом эта функция устанавливает текущую позицию на pos , возвращая истину в случае успеха или ложь в случае ошибки. Для последовательных устройств поведение по умолчанию - ничего не делать и возвращать false.

Поиск за пределами конца файла: если позиция находится за пределами конца файла, функция seek () не будет немедленно расширять файл. Если запись выполняется в эту позицию, файл будет расширен. Содержимое файла между предыдущим концом файла и вновь записанными данными НЕОПРЕДЕЛЕННО и варьируется в зависимости от платформы и файловой системы.

bool QFileDevice :: setFileTime (const QDateTime &

newDate , QFileDevice :: FileTime fileTime )

Устанавливает время файла, заданное параметром fileTime , равным newDate , возвращая истину в случае успеха; в противном случае возвращает false.

Примечание: Для использования этой функции файл должен быть открыт.

Эта функция была представлена ​​в Qt 5.10.

См. Также fileTime () и FileTime.

[виртуальный] bool QFileDevice :: setPermissions (QFileDevice :: Permissions разрешения )

Устанавливает для файла права доступа , указанные .Возвращает true в случае успеха или false , если разрешения не могут быть изменены.

Предупреждение: Эта функция не управляет списками ACL, что может ограничить ее эффективность.

См. Также разрешения ().

[переопределить виртуальный] qint64 QFileDevice :: size () const

Переопределения: QIODevice :: size () const.

Возвращает размер файла.

Для обычных пустых файлов в Unix (например, в / proc ) эта функция возвращает 0; содержимое такого файла создается по запросу в ответ на ваш вызов read ().

bool QFileDevice :: unmap (uchar *

адрес )

Отключает отображение памяти по адресу .

Возвращает true , если unmap успешно; в противном случае - ложь.

См. Также карту ().

void QFileDevice :: unsetError ()

Устанавливает для файла ошибку QFileDevice :: NoError.

См. Также ошибку ().

[переопределить виртуальную защиту] qint64 QFileDevice :: writeData (const char * data , qint64 len )

Переопределения: QIODevice :: writeData (const char * data, qint64 maxSize).

Класс QTemporaryFile | Qt Core 5.15.4

Класс QTemporaryFile - это устройство ввода-вывода, которое работает с временными файлами. Подробнее ...

Подробное описание

QTemporaryFile используется для безопасного создания уникальных временных файлов. Сам файл создается путем вызова open (). Имя временного файла гарантированно уникально (т.е. вы гарантированно не перезаписываете существующий файл), и файл впоследствии будет удален после уничтожения объекта QTemporaryFile.Это важный метод, позволяющий избежать повреждения данных для приложений, хранящих данные во временных файлах. Имя файла либо автоматически генерируется, либо создается на основе шаблона, который передается конструктору QTemporaryFile.

Пример:

Повторное открытие QTemporaryFile после вызова close () безопасно. Пока сам объект QTemporaryFile не уничтожен, уникальный временный файл будет существовать и будет оставаться открытым внутри QTemporaryFile.

Имя временного файла можно узнать, вызвав fileName ().Обратите внимание, что это определяется только после первого открытия файла; перед этим функция возвращает пустую строку.

Временный файл будет иметь некоторую статическую часть имени и некоторую часть, которая считается уникальной. Имя файла по умолчанию будет определено из QCoreApplication :: applicationName () (иначе qt_temp ) и будет помещено во временный путь, возвращенный QDir :: tempPath (). Если вы укажете собственное имя файла, относительный путь к файлу по умолчанию не будет помещен во временный каталог, а будет относиться к текущему рабочему каталогу.

Указанные имена файлов могут содержать следующий шаблон XXXXXX (шесть символов «X» в верхнем регистре), который будет заменен автоматически сгенерированной частью имени файла. Обратите внимание, что в шаблоне учитывается регистр. Если шаблон отсутствует в имени файла, QTemporaryFile добавляет сгенерированную часть к данному имени файла.

Примечание: В Linux QTemporaryFile попытается создать безымянные временные файлы. Если это удастся, open () вернет true, а exists () будет false.Если вы вызываете fileName () или любую вызывающую его функцию, QTemporaryFile даст файлу имя, поэтому большинство приложений не заметят разницы.

Документация по функциям-членам

QTemporaryFile :: QTemporaryFile (const QString &

templateName , QObject * родительский )

Создает QTemporaryFile с именем файла шаблона templateName и указанным родительским элементом . После открытия временного файла он будет использован для создания уникального имени файла.

Если templateName не содержит XXXXXX, он будет автоматически добавлен и использован как динамическая часть имени файла.

Если имя_шаблона - относительный путь, путь будет относиться к текущему рабочему каталогу. Вы можете использовать QDir :: tempPath () для создания templateName , если вы хотите использовать временный каталог системы.

См. Также open () и fileTemplate ().

QTemporaryFile :: QTemporaryFile (QObject *

родительский )

Создает QTemporaryFile (с заданным родительским файлом ), используя в качестве шаблона файла имя приложения, возвращаемое QCoreApplication :: applicationName () (в противном случае qt_temp ), за которым следует ".XXXXXX ". Файл хранится во временном каталоге системы QDir :: tempPath ().

См. Также setFileTemplate ().

QTemporaryFile :: QTemporaryFile (const QString &

имя шаблона )

Создает QTemporaryFile с именем файла шаблона имя_шаблона . После открытия временного файла он будет использован для создания уникального имени файла.

Если templateName не содержит XXXXXX, он будет автоматически добавлен и использован как динамическая часть имени файла.

Если имя_шаблона - относительный путь, путь будет относиться к текущему рабочему каталогу. Вы можете использовать QDir :: tempPath () для создания templateName , если вы хотите использовать временный каталог системы.

См. Также open () и fileTemplate ().

QTemporaryFile :: QTemporaryFile ()

Создает QTemporaryFile, используя в качестве шаблона файла имя приложения, возвращаемое QCoreApplication :: applicationName () (иначе qt_temp ), за которым следует ".XXXXXX ". Файл хранится во временном каталоге системы QDir :: tempPath ().

См. Также setFileTemplate () и QDir :: tempPath ().

[виртуальный] QTemporaryFile :: ~ QTemporaryFile ()

Уничтожает временный файловый объект, при необходимости файл автоматически закрывается, а в режиме автоматического удаления он автоматически удаляет файл.

См. Также autoRemove ().

bool QTemporaryFile :: autoRemove () const

Возвращает true , если QTemporaryFile находится в режиме автоматического удаления.В режиме автоматического удаления имя файла автоматически удаляется с диска при уничтожении. Это позволяет очень легко создать объект QTemporaryFile в стеке, заполнить его данными, прочитать из него и, наконец, при возврате функции он автоматически очистится после себя.

Автоудаление включено по умолчанию.

См. Также setAutoRemove () и remove ().

[статические] QTemporaryFile * QTemporaryFile :: createNativeFile (QFile и файл )

Если файл еще не является собственным файлом, то QTemporaryFile создается в QDir :: tempPath (), содержимое файла копируется в него, и возвращается указатель на временный файл.Ничего не делает и возвращает 0 , если файл уже является собственным файлом.

Например:

См. Также QFileInfo :: isNativePath ().

[статические] QTemporaryFile * QTemporaryFile :: createNativeFile (const QString & имя_файла )

Это перегруженная функция.

Работает с заданным fileName , а не с существующим объектом QFile.

[переопределить виртуальный] QString QTemporaryFile :: fileName () const

Переопределения: QFile :: fileName () const.

Возвращает полное уникальное имя файла, поддерживающее объект QTemporaryFile. Эта строка имеет значение NULL до открытия QTemporaryFile, после этого она будет содержать fileTemplate () плюс дополнительные символы, чтобы сделать ее уникальной.

См. Также fileTemplate ().

QString QTemporaryFile :: fileTemplate () const

Возвращает установленный шаблон файла. Шаблон файла по умолчанию будет называться qcoreappname.XXXXXX и помещаться в QDir :: tempPath ().

См. Также setFileTemplate ().

bool QTemporaryFile :: open ()

QTemporaryFile всегда будет открыт в режиме QIODevice :: ReadWrite, это обеспечивает легкий доступ к данным в файле. Эта функция вернет истину в случае успеха и установит для fileName () уникальное имя используемого файла.

См. Также fileName ().

[переопределить виртуальную защиту] bool QTemporaryFile :: open (QIODevice :: OpenMode flags )

Переопределения: QFile :: open (режим QIODevice :: OpenMode).

Создает уникальное имя временного файла и открывает его. Позже вы можете получить уникальное имя, вызвав fileName (). Гарантируется, что файл был создан этой функцией (т.е. он никогда не существовал раньше).

void QTemporaryFile :: setAutoRemove (bool

b )

Устанавливает QTemporaryFile в режим автоматического удаления, если b имеет значение true .

Автоудаление включено по умолчанию.

Если вы установите для этого свойства значение false , убедитесь, что приложение предоставляет способ удаления файла, когда он больше не нужен, включая передачу ответственности другому процессу.Всегда используйте функцию fileName () для получения имени и никогда не пытайтесь угадать имя, которое сгенерировал QTemporaryFile.

В некоторых системах, если fileName () не вызывается перед закрытием файла, временный файл может быть удален независимо от состояния этого свойства. На такое поведение нельзя полагаться, поэтому код приложения должен либо вызвать fileName (), либо оставить включенной функцию автоматического удаления.

См. Также autoRemove () и remove ().

void QTemporaryFile :: setFileTemplate (const QString &

имя )

Устанавливает статическую часть имени файла на имя .Если шаблон файла содержит XXXXXX, который будет автоматически заменен уникальной частью имени файла, в противном случае имя файла будет определено автоматически на основе указанной статической части.

Если имя содержит относительный путь к файлу, путь будет относиться к текущему рабочему каталогу. Вы можете использовать QDir :: tempPath () для создания name , если вы хотите использовать временный каталог системы.

См. Также fileTemplate ().

Запуск внешних программ в PyQt5 с помощью QProcess, с потоками и индикаторами выполнения

До сих пор мы рассмотрели, как выполнять работу в отдельных потоках, что позволяет выполнять сложные задачи, не прерывая пользовательский интерфейс.Это отлично работает при использовании библиотек Python для выполнения задач, но иногда вам нужно запускать внешние приложения, передавать параметры и получать результаты.

В этом руководстве мы рассмотрим QProcess , систему Qt для запуска внешних программ из вашего собственного приложения.

Внешняя программа

Чтобы иметь возможность тестировать запуск внешних программ с помощью QProcess , нам нужно что-то запустить. Здесь мы создадим для этой цели простой скрипт Python, который затем можно будет запустить из нашего приложения.Поместите следующее в файл и сохраните его с именем dummy_script.py .

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

Не беспокойтесь о содержимом этого скрипта, это просто серия операторов print (потоковая запись) с ожиданием в полсекунды после. Это имитирует длительную внешнюю программу, которая периодически выводит сообщения о состоянии.Позже мы увидим, как извлечь данные из этого вывода.

питон
  импорт систем
время импорта


def flush_then_wait ():
    sys.stdout.flush ()
    sys.stderr.flush ()
    time.sleep (0,5)


sys.stdout.write ("Стандартный вывод сценария 1 \ n")
sys.stdout.write ("Стандартный вывод сценария 2 \ n")
sys.stdout.write ("Стандартный вывод сценария 3 \ n")
sys.stderr.write ("Общее время: 00: 05: 00 \ n")
sys.stderr.write ("Всего выполнено: 10% \ n")
flush_then_wait ()

sys.stdout.write ("name = Мартин \ n")
sys.stdout.write ("Стандартный вывод сценария 4 \ n")
sys.stdout.write ("Сценарий stdout 5 \ n")
sys.stderr.write ("Всего выполнено: 30% \ n")
flush_then_wait ()

sys.stderr.write ("Прошедшее время: 00: 00: 10 \ n")
sys.stderr.write ("Прошедшее время: 00: 00: 50 \ n")
sys.stderr.write ("Всего выполнено: 50% \ n")
sys.stdout.write ("страна = Нидерланды \ n")
flush_then_wait ()

sys.stderr.write ("Прошедшее время: 00: 01: 10 \ n")
sys.stderr.write ("Всего выполнено: 100% \ n")
sys.stdout.write ("Стандартный вывод сценария 6 \ n")
sys.stdout.write ("Стандартный вывод сценария 7 \ n")
sys.stdout.write ("сайт = www.mfitzp.com \ n")
flush_then_wait ()

  

Теперь у нас есть dummy_script.py , мы можем запустить его из нашего приложения Qt.

Базовое приложение

Чтобы поэкспериментировать с запуском программ через QProcess , нам понадобится скелет приложения. Это показано ниже - простое окно с QPushButton и QTextArea . Нажатие кнопки вызывает наш пользовательский слот start_process , в котором мы будем выполнять наш внешний процесс.

питон
  из импорта PyQt5.QtWidgets (QApplication, QMainWindow, QPushButton, QPlainTextEdit,
                                QVBoxLayout, QWidget)
из PyQt5.QtCore import QProcess
import sys


класс MainWindow (QMainWindow):

    def __init __ (сам):
        супер () .__ init __ ()

        self.btn = QPushButton ("Выполнить")
        self.btn.pressed.connect (self.start_process)
        self.text = QPlainTextEdit ()
        self.text.setReadOnly (Истина)

        l = QVBoxLayout ()
        l.addWidget (self.btn)
        l.addWidget (самотекст)

        w = QWidget ()
        w.setLayout (l)

        self.setCentralWidget (w)

    def start_process (сам):
        # Здесь мы запустим наш процесс.проходить

app = QApplication (sys.argv)

w = MainWindow ()
w.show ()

app.exec_ ()
  

Убедитесь, что работает, смотреть пока особо не на что - нажатие кнопки тоже ничего не делает.

Скелет приложения.

Использование

QProcess для выполнения внешних приложений.

Выполнение внешних программ с помощью QProcess довольно просто. Сначала вы создаете объект QProcess , а затем вызываете .start () передает команду для выполнения и список строковых аргументов.

питон
  p = QProcess ()
p.start ("<программа>", [<аргументы>])
  

В нашем примере мы запускаем пользовательский сценарий dummy_script.py с Python, поэтому наш исполняемый файл - python (или python3 ), а наши аргументы - всего лишь dummy_script.py .

питон
  p = QProcess ()
п.start ("python3", ['dummy_script.py'])
  

Если вы запускаете другую программу командной строки, вам необходимо указать для нее аргументы. Например, использование ffmpeg для извлечения информации из видеофайла.

питон
  p = QProcess ()
p.start ("ffprobe", ['-show_format', '-show_streams', 'a.mp4.py'])
  

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

Мы можем взять пример p.start ("python3", ['dummy_script.py']) и добавить его в скелет нашего приложения следующим образом. Мы также добавляем вспомогательный метод message () для записи сообщений в текстовое поле пользовательского интерфейса.

питон
  из импорта PyQt5.QtWidgets (QApplication, QMainWindow, QPushButton, QPlainTextEdit,
                                QVBoxLayout, QWidget)
из PyQt5.QtCore импорт QProcess
import sys


класс MainWindow (QMainWindow):

    def __init __ (сам):
        супер().__в этом__()

        self.btn = QPushButton ("Выполнить")
        self.btn.pressed.connect (self.start_process)
        self.text = QPlainTextEdit ()
        self.text.setReadOnly (Истина)

        l = QVBoxLayout ()
        l.addWidget (self.btn)
        l.addWidget (самотекст)

        w = QWidget ()
        w.setLayout (l)

        self.setCentralWidget (w)

    сообщение def (self, s):
        self.text.appendPlainText (s)

    def start_process (сам):
        self.message («Процесс выполнения.»)
        self.p = QProcess () # Сохранять ссылку на QProcess (например,грамм. на себя) во время работы.
        self.p.start ("python3", ['dummy_script.py'])


app = QApplication (sys.argv)

w = MainWindow ()
w.show ()

app.exec_ ()
  

Обратите внимание, что вы должны сохранять ссылку на созданный объект QProcess во время его работы, например на сам.п. . В противном случае объект будет удален преждевременно, и вы увидите сообщение QProcess: Destroyed, пока процесс ("python3") все еще выполняется. Ошибка .

Если вы запустите этот пример и нажмете кнопку, ничего не произойдет.Внешний скрипт запущен, но вы не видите вывода.

Отображается сообщение о выполнении, но ничего больше.

Если вы нажмете кнопку несколько раз, вы можете увидеть такое сообщение -

трепать
  QProcess: уничтожено, пока процесс ("python3") все еще выполняется.
  

Это связано с тем, что если вы нажмете кнопку , когда процесс уже запущен , создание нового процесса заменяет ссылку на существующий объект QProcess в self.p , удалив его. Мы можем избежать этого, проверив значение self.p перед выполнением нового процесса и подключив сигнал завершено , чтобы сбросить его обратно на Нет , например

питон
  из импорта PyQt5.QtWidgets (QApplication, QMainWindow, QPushButton, QPlainTextEdit,
                                QVBoxLayout, QWidget)
из PyQt5.QtCore импорт QProcess
import sys


класс MainWindow (QMainWindow):

    def __init __ (сам):
        супер().__в этом__()

        self.p = None # Пустое значение по умолчанию.

        self.btn = QPushButton ("Выполнить")
        self.btn.pressed.connect (self.start_process)
        self.text = QPlainTextEdit ()
        self.text.setReadOnly (Истина)

        l = QVBoxLayout ()
        l.addWidget (self.btn)
        l.addWidget (самотекст)

        w = QWidget ()
        w.setLayout (l)

        self.setCentralWidget (w)

    сообщение def (self, s):
        self.text.appendPlainText (s)

    def start_process (сам):
        если сам.p равно None: # Ни один процесс не запущен.
            self.message («Процесс выполнения»)
            self.p = QProcess () # Сохранять ссылку на QProcess (например, на себя) во время его работы.
            self.p.finished.connect (self.process_finished) # Очистить после завершения.
            self.p.start ("python3", ['dummy_script.py'])

    def process_finished (сам):
        self.message («Процесс завершен.»)
        self.p = Нет


app = QApplication (sys.argv)

w = MainWindow ()
w.show ()

app.exec_ ()
  

Запустив это сейчас, вы можете запустить процесс, а после его завершения - запустить его снова.Каждый раз, когда процесс завершится, вы увидите сообщение «Процесс завершен». сообщение в текстовом поле.

Сообщение «Процесс завершен» отображается после его завершения.

Получение данных из

QProcess

Пока что мы выполнили внешнюю программу и получили уведомления о ее запуске и остановке, но ничего не знаем о том, что она делает. Это нормально в некоторых случаях, когда вы просто хотите, чтобы задание выполнялось, но часто вам нужны более подробные отзывы. К счастью, QProcess предоставляет ряд сигналов, которые можно использовать для отслеживания хода и состояния процессов.

Если вы знакомы с запуском внешних процессов с использованием подпроцесса в Python, возможно, вы знакомы с потоками . Это файловые объекты, которые вы используете для извлечения данных из запущенного процесса. Два стандартных потока: стандартный вывод и стандартный поток ошибок . Первый получает результат данных, выводимых приложением, а второй получает диагностических или сообщений об ошибке . В зависимости от того, что вас интересует, оба из них могут быть полезны - многие программы (например, наш dummy_script.py выводит информацию о ходе выполнения в поток стандартной ошибки .

В области Qt применяются те же принципы. Объект QProcess имеет два сигнала .readyReadStandardOutput и .readyReadStandardError , которые используются для уведомления, когда данные доступны в соответствующих потоках. Затем мы можем читать из процесса, чтобы получить самые свежие данные.

Ниже приведен пример настройки QProcess , который соединяет readyReadStandardOutput и .readyReadStandardError , а также отслеживание изменений состояния и сигналов завершения.

питон
  p = QProcess ()
p.readyReadStandardOutput.connect (self.handle_stdout)
p.readyReadStandardError.connect (self.handle_stderr)
p.stateChanged.connect (self.handle_state)
p.finished.connect (самоочистка)
p.start ("питон", ["dummy_script.py"])
  

Сигнал .stateChanged срабатывает при изменении статуса процесса. Допустимые значения - определены в QProcess.Перечисление ProcessState - показаны ниже.

Константа Значение Описание
QProcess.NotRunning 0 Процесс не запущен.
QProcess.Starting 1 Процесс запускается, но программа еще не запущена.
QProcess.Running 2 Процесс запущен и готов к чтению и записи.

Включение этого в наш пример и реализация методов обработчика для каждого из них дает нам следующий полный код.

питон
  из импорта PyQt5.QtWidgets (QApplication, QMainWindow, QPushButton, QPlainTextEdit,
                                QVBoxLayout, QWidget)
из PyQt5.QtCore импорт QProcess
import sys


класс MainWindow (QMainWindow):

    def __init __ (сам):
        супер () .__ init __ ()

        self.p = Нет

        себя.btn = QPushButton ("Выполнить")
        self.btn.pressed.connect (self.start_process)
        self.text = QPlainTextEdit ()
        self.text.setReadOnly (Истина)

        l = QVBoxLayout ()
        l.addWidget (self.btn)
        l.addWidget (самотекст)

        w = QWidget ()
        w.setLayout (l)

        self.setCentralWidget (w)

    сообщение def (self, s):
        self.text.appendPlainText (s)

    def start_process (сам):
        если self.p равен None: # Процесс не запущен.
            self.message («Процесс выполнения»)
            себя.p = QProcess () # Сохранять ссылку на QProcess (например, на себя) во время его работы.
            self.p.readyReadStandardOutput.connect (self.handle_stdout)
            self.p.readyReadStandardError.connect (self.handle_stderr)
            self.p.stateChanged.connect (self.handle_state)
            self.p.finished.connect (self.process_finished) # Очистить после завершения.
            self.p.start ("python3", ['dummy_script.py'])

    def handle_stderr (сам):
        data = self.p.readAllStandardError ()
        stderr = байты (данные).декодировать ("utf8")
        self.message (stderr)

    def handle_stdout (сам):
        data = self.p.readAllStandardOutput ()
        stdout = байты (данные) .decode ("utf8")
        self.message (стандартный вывод)

    def handle_state (себя, состояние):
        состояния = {
            QProcess.NotRunning: 'Не работает',
            QProcess.Starting: 'Запуск',
            QProcess.Running: 'Выполняется',
        }
        state_name = состояния [состояние]
        self.message (f "Состояние изменено: {state_name}")

    def process_finished (сам):
        себя.сообщение ("Процесс завершен.")
        self.p = Нет


app = QApplication (sys.argv)

w = MainWindow ()
w.show ()

app.exec_ ()
  

Если вы запустите это, вы увидите, что стандартный вывод, стандартная ошибка, изменения состояния и сообщения о запуске / остановке печатаются в текстовом поле. Обратите внимание, что мы конвертируем состояния обратно в дружественные строки перед выводом (используя dict для сопоставления из значений перечисления).

Выходные данные нашего настраиваемого сценария показаны в текстовом поле.

Обработка вывода немного сложна и заслуживает более внимательного рассмотрения.

питон
  data = self.p.readAllStandardError ()
        stderr = байты (данные) .decode ("utf8")
        self.message (stderr)
  

Это необходимо, потому что QProcess.readAllStandardError и QProcess.readAllStandardOutput возвращают данные как байты, заключенные в объект Qt. Сначала мы должны преобразовать это в объект Python bytes () , а затем декодировать этот байтовый поток в строку (здесь используется кодировка UTF8).

Анализ данных из вывода процесса

В настоящее время мы просто выгружаем вывод программы в текстовое поле, но что, если бы мы хотели извлечь из него какие-то конкретные данные? Обычно это используется для отслеживания прогресса запущенной программы, чтобы мы могли отображать индикатор выполнения по мере ее завершения.

В этом примере наш демонстрационный скрипт dummy_script.py возвращает серию строк, включая строки стандартной ошибки , которые показывают текущий процент завершения прогресса - e.грамм. Всего выполнено: 50% . Мы можем обработать эти строки до прогресса и показать это в строке состояния.

В приведенном ниже примере мы извлекаем это с помощью специального регулярного выражения . Функция simple_percent_parser сопоставляет содержимое потока стандартной ошибки и извлекает число от 00 до 100 для прогресса. Это значение используется для обновления индикатора выполнения, добавленного в пользовательский интерфейс.

питон
  из PyQt5.Импорт QtWidgets (QApplication, QMainWindow, QPushButton, QPlainTextEdit,
                                QVBoxLayout, QWidget, QProgressBar)
из PyQt5.QtCore импорт QProcess
import sys
импорт ре

# Регулярное выражение для извлечения% завершения.
progress_re = re.compile ("Всего выполнено: (\ d +)%")

def simple_percent_parser (вывод):
    "" "
    Соответствует строкам с использованием регулярного выражения progress_re,
    возвращает одно целое число для% прогресса.
    "" "
    m = progress_re.search (вывод)
    если М:
        pc_complete = м.группа 1)
        вернуть int (pc_complete)


класс MainWindow (QMainWindow):

    def __init __ (сам):
        супер () .__ init __ ()

        self.p = Нет

        self.btn = QPushButton ("Выполнить")
        self.btn.pressed.connect (self.start_process)
        self.text = QPlainTextEdit ()
        self.text.setReadOnly (Истина)

        self.progress = QProgressBar ()
        self.progress.setRange (0, 100)

        l = QVBoxLayout ()
        l.addWidget (self.btn)
        l.addWidget (self.progress)
        l.addWidget (self.текст)

        w = QWidget ()
        w.setLayout (l)

        self.setCentralWidget (w)

    сообщение def (self, s):
        self.text.appendPlainText (s)

    def start_process (сам):
        если self.p равен None: # Процесс не запущен.
            self.message («Процесс выполнения»)
            self.p = QProcess () # Сохранять ссылку на QProcess (например, на себя) во время его работы.
            self.p.readyReadStandardOutput.connect (self.handle_stdout)
            self.p.readyReadStandardError.connect (self.handle_stderr)
            self.p.stateChanged.connect (self.handle_state)
            self.p.finished.connect (self.process_finished) # Очистить после завершения.
            self.p.start ("python3", ['dummy_script.py'])

    def handle_stderr (сам):
        data = self.p.readAllStandardError ()
        stderr = байты (данные) .decode ("utf8")
        # Извлечь прогресс, если он есть в данных.
        прогресс = простой_перцент_парсер (stderr)
        если прогресс:
            self.progress.setValue (прогресс)
        себя.сообщение (stderr)

    def handle_stdout (сам):
        data = self.p.readAllStandardOutput ()
        stdout = байты (данные) .decode ("utf8")
        self.message (стандартный вывод)

    def handle_state (себя, состояние):
        состояния = {
            QProcess.NotRunning: 'Не работает',
            QProcess.Starting: 'Запуск',
            QProcess.Running: 'Выполняется',
        }
        state_name = состояния [состояние]
        self.message (f "Состояние изменено: {state_name}")

    def process_finished (сам):
        self.message ("Процесс завершен.")
        self.p = Нет


app = QApplication (sys.argv)

w = MainWindow ()
w.show ()

app.exec_ ()
  

Если вы запустите это и запустите процесс, вы увидите, что индикатор выполнения постепенно заполняется по мере получения сообщений о ходе выполнения от dummy_script.py , проходящего через QProcess .

Индикатор выполнения заполняется по мере завершения сценария.

Этот подход хорошо работает с любыми программами командной строки - в некоторых случаях вы можете захотеть проанализировать стандартный вывод , а не стандартную ошибку , но принципы идентичны.Иногда программы не дают вам заранее рассчитанного значения прогресса, и вам нужно проявить немного творчества. Если вам нравится задача, попробуйте изменить синтаксический анализатор, чтобы извлечь данные общего времени и прошедшего времени из стандартной ошибки dummy_script.py и использовать их для вычисления индикатора выполнения. Вы также можете попробовать адаптировать запуск для других программ командной строки.

Дальнейшие улучшения

Во всех этих примерах мы храним ссылку на процесс в self.p , что означает, что мы можем одновременно запустить только один процесс. Но вы можете запускать столько процессов, сколько захотите, вместе с вашим приложением. Если вам не нужно отслеживать информацию от них, вы можете просто сохранить ссылки на процессы в списке .

Если вы запускаете несколько внешних программ одновременно и хотят отслеживать их состояния, вы можете подумать о создании класса менеджера , который сделает это за вас. Книга содержит больше примеров, в том числе этот менеджер, объединяющий анализ стандартного вывода QProcess с представлениями модели для создания монитора выполнения в реальном времени для внешних процессов.

Диспетчер процессов, показывающий активные процессы и ход выполнения

CentOS Stream, Cyberpunk 2077 для Linux, Qt 6.0, магазин приложений Flatpak | На этой неделе в Linux 129

Спасибо, @MichaelTunnell! Отличное зрелище, как всегда

Большое спасибо за более подробное изучение вопроса о CentOS / CentOS Stream , и да, мне бы хотелось посмотреть видео, если у вас есть время. Я предполагаю, что моей главной заботой было иметь доступ к RHEL , если я когда-либо буду обучаться для их сертификации, и CentOS был хорошим способом экспериментировать, сколько угодно, без необходимости платить лицензионный сбор Enterprise.Однако, если есть бесплатная версия для разработчиков, это будет даже лучше, я согласен. Я могу понять подход CentOS Stream к инновациям, хотя я опасаюсь, что он может иметь довольно большое значение с точки зрения риска / надежности. С другой стороны, я очень консервативен и не склонен рисковать в отношении ежедневных водителей. Debian меня очень устраивает, и, честно говоря, я бы более чем вероятно подумал, что если мне понадобится небольшое количество серверов, а не RHEL. Если вы ведете бизнес, зависящий от программного обеспечения корпоративного уровня, я действительно думаю, что вложение в техническую поддержку RedHat, вероятно, будет хорошей идеей и стоит, хотя стартапам поначалу может быть сложно. Rocky Linux может еще спасти положение для таких людей, но я бы хотел, чтобы их выбор имени был эээ… другим. На мой взгляд, у Рокки нет коннотации стабильности!

Раньше я мало слышал о Crux Linux . Звучит интересно, например, Slackware , который был первым дистрибутивом, который я когда-либо устанавливал. Все было в виде tar-файлов. Звучит немного как LFS тоже

Risc-V меня действительно интересует, поэтому я с нетерпением жду увеличения поддержки этого в QEMU .Также я рад, что Qt вводит новшества, даже если временами не поддерживает обратную совместимость, поскольку, на мой взгляд, у нас острая потребность в портативном инструментарии графического интерфейса. Я начинаю получать больше удовольствия от JavaFX , поскольку теперь он наконец-то переносится и на мобильные платформы. Как только у меня будет опыт работы с ним для настольных компьютеров, я попробую его для Android, чьи собственные инструменты неоднократно подводили меня, когда я смотрел на них год или два назад.

▷ 62 часа видео и потоковой передачи QT Marshall, май 2021 г.

▷ 62 часа видео и потоковой передачи QT Marshall, май 2021 г. - FITE FacebookTwitterInstagramPinterestLinkedIn
  • AEW Dark Elevation, Серия 10-21

    PPV AEW Plus 5.0

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    02:27:52
    Жанры:
    Реслинг
    Бойцов:
    Джейк Робертс "Змея", Скорпион Небо, Пента Эль Зером М, Брайан Кейдж, Мальчик из джунглей, Итан Пейдж, Адриан Аланис, Эдди Кингстон, Ройс Айзекс, Марко Стант, Наталья Маркова, Дастин Роудс, Дэнни Лаймлайт, Джон Моксли, Аарон Солоу, Лэнс Арчер, QT Маршалл, Лейла Хирш, Килинн Кинг, Зайчик, Барон Блэк, Тай Конти, Кевин Блэквуд, Крюк, Майк Сидал, Медведь Бронсон, Киа Мечта, Робо, Джейлен Брэндин, Трэвон Джордан, Кевин Беннетт

  • AEW: Дважды или ничего 2021

    PPV 4.8721

    Канал:
    Вся элитная борьба
    Время эфира:
    Жанры:
    Реслинг
    Место:
    Daily's Place, Джэксонвилл, Флорида
    Бойцов:
    Адам Пейдж "Палач", Коди Роудс, Мэтт Сидал, Кенни Омега, Арн Андерсон, Брайан Кейдж, Апельсин Кэссиди, PAC, Доктор Бритт Бейкер, Хикару Шида, Аарон Солоу, ТАЗ, QT Маршалл, Ник Коморото, Дон Каллис, Кристиан Кейдж, Бунтарь, Энтони Огого

  • AEW Dark Elevation, Серия 08-21

    PPV AEW Plus 4.6667

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    01:40:19
    Жанры:
    Реслинг
    Бойцов:
    Рё Мизунами, Кольт Кабана, Мэтт Харди, Уилл Алдей, Громовая Роза, Нила Роуз, Джон Моксли, Диллон МакКуин, Лезвие, Исайя Кэссиди, Марк Квен, QT Маршалл, Алан Ангелы, Красный вельвет, Покидать, Вики Герреро, Миро, Мади Вренковски, Андреевский дворец, Герцог Дэвис, Ганон Джонс, Река Техака

  • AEW: Динамит, Серия 17-21

    PPV AEW Plus 4.8108

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    02:00:00
    Жанры:
    Реслинг
    Место:
    Daily's Place, Джэксонвилл, Флорида
    Бойцов:
    Адам Пейдж "Палач", Мэтт Джексон, Ник Джексон, Мэтт Сидал, Дарби Аллин, Пента Эль Зером М, Брайан Кейдж, Апельсин Кэссиди, Дастин Роудс, Пенелопа Форд, Крис Статлендер, QT Маршалл, Майк Сидал

  • AEW Dark, Серия 15-21

    Бесплатно 5.0

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    01:35:16
    Жанры:
    Реслинг
    Место:
    Daily's Place, Джэксонвилл, Флорида
    Бойцов:
    Кольт Кабана, Мэтт Сидал, Мэтт Харди, Брайан Кейдж, Уилл Алдей, Джей Ди Дрейк, Камень Роквелл, Доктор Бритт Бейкер, Нила Роуз, Билли Ганн, Аарон Солоу, Лэнс Арчер, SCU, Королева Амината, Большой Свол, Фуэго-дель-Соль, Остин Ганн, Алекс Рейнольдс, Рики Старкс, Зло Уно, Стю Грейсон, QT Маршалл, Лютер, Килинн Кинг, Красный вельвет, Кен Бродвей, Ник Коморото, Вики Герреро, Электростанция Хоббса, Майк Магнум, Мади Вренковски, Вари Моралес, Крюк, Янтарная Нова, Райан Немет, Карли Браво, Декан Александр, Лейла Грей, Хайден Баклунд, Джей Лайон, Мидас Блэк, Ки Сакетт, Джейк Мэннинг, Андреевский дворец, Спенсер Слейд, Шона Рид, Принц Кай, Коул Картер

  • AEW: Динамит, Серия 13-21

    PPV AEW Plus 4.8737

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    02:00:00
    Жанры:
    Реслинг
    Место:
    Daily's Place, Джэксонвилл, Флорида
    Бойцов:
    Чак Тейлор, Коди Роудс, Фрэнки Казарян, Ларедо Кид, Кенни Омега, Арн Андерсон, Мэтт Харди, Пентагон-младший, Рей Феникс, Апельсин Кэссиди, MJF, Нила Роуз, Хикару Шида, Кип Сабиан, Пенелопа Форд, QT Маршалл, Зайчик, Док Гэллоуз "Большой LG", Карл Андерсон, Люк Гэллоус, Тай Конти, Вики Герреро, Миро, Дон Каллис, Кристиан Кейдж

  • AEW Dark, Серия 12-21

    Бесплатно 4.4

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    01:39:12
    Жанры:
    Реслинг
    Место:
    Daily's Place, Джэксонвилл, Флорида
    Бойцов:
    Кольт Кабана, Мясник, Джои Джанела, Брайан Кейдж, Джон Скайлер, Джей Ди Дрейк, Джек Эванс, Ройс Айзекс, Джорел Нельсон, Джон Сильвер, Алекс Грация, Эшли Вокс, Билли Ганн, Аарон Солоу, Кип Сабиан, SCU, Брэндон Катлер, Пенелопа Форд, Сонни Кисс, Фуэго-дель-Соль, Остин Ганн, Миранда Ализе "СУПЕРСТАР", Алекс Рейнольдс, Лезвие, Питер Авалон "Библиотекарь", Зло Уно, Стю Грейсон, QT Маршалл, Шон Дин, Зайчик, Барон Блэк, Цезарь Бонони, Ангельская мода, Ник Коморото, Адам Прист, Сет Гаргис, Джазмин Аллюр, Вари Моралес, Данте Мартин, Крюк, Джейк Ст.Патрик, Карли Браво, Брик Олдридж, Декан александр

  • AEW Dark Elevation, Серия 01-21

    PPV AEW Plus 4,6111

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    02:01:11
    Жанры:
    Реслинг
    Бойцов:
    Мэтт Сидал, Мясник, Мэтт Харди, Мальчик из джунглей, Ройс Айзекс, Джорел Нельсон, Марко Стант, Эшли Вокс, Рихо, Дэнни Лаймлайт, Кип Сабиан, Брэндон Катлер, Пенелопа Форд, Лучазавр, Большой Свол, Лезвие, Рэй Лин, Исайя Кэссиди, Марк Квен, QT Маршалл, Скайлер Мур, Диаманте, Маки Ито, АБАДОН, Дани Джордин, Зайчик, Дэвид Али, Красный вельвет, Макс Кастер, Барон Блэк, Тай Конти, Миро, Электростанция Хоббса, Вари Моралес, Данте Мартин, Крюк, Карли Браво, Майк Сидал, Брик Олдридж, Декан Александр, Лейла Грей

  • AEW Dark, Серия 10-21

    Бесплатно 4.7

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    01:30:28
    Жанры:
    Реслинг
    Место:
    Daily's Place, Джэксонвилл, Флорида
    Бойцов:
    Кольт Кабана, Джои Джанела, Сантана, Ортис, Дэнни Лаймлайт, Аарон Солоу, Кип Сабиан, SCU, Пенелопа Форд, Сонни Кисс, Фуэго-дель-Соль, Каталина Перес, Алекс Рейнольдс, Зло Уно, Стю Грейсон, QT Маршалл, Диаманте, АБАДОН, Джон Круз, Шон Дин, Ли Джонсон, Рызин, Барон Блэк, Ангельская мода, Ник Коморото, Электростанция Хоббса, Вари Моралес, Крюк, Райан Немет, Карли Браво, Аарон Фрай, Азриэль, Брик Олдридж, Декан Александр, Кэмерон Стюарт, Студенческие блондинки, Саванна Торн

  • AEW Dark, Серия 08-21

    Бесплатно 4.9

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    02:13:38
    Жанры:
    Реслинг
    Место:
    Daily's Place, Джэксонвилл, Флорида
    Бойцов:
    Коди Роудс, Арн Андерсон, Джои Джанела, Брайан Кейдж, Мальчик из джунглей, Ивелисс, Джон Скайлер, Джей Ди Дрейк, Эдди Кингстон, Энтони Боуэнс, Джон Сильвер, Марко Стант, Аарон Солоу, Кип Сабиан, Пенелопа Форд, Лучазавр, Сонни Кисс, Фуэго-дель-Соль, Миранда Ализе "СУПЕРСТАР", Серпентико, Алекс Рейнольдс, Дж. Дж. Гарретт, Питер Авалон "Библиотекарь", QT Маршалл, Диаманте, Лютер, Шон Дин, Ли Джонсон, Килинн Кинг, Макс Кастер, М’Баду, Рызин, Барон Блэк, Цезарь Бонони, Ангельская мода, Ник Коморото, Луи Валле, Теша Прайс, Крюк, Брук Хэвок, Райан Немет, Карли Браво, Рене Мишель, Крис Пикс, Лейла Хирш, Тони Вега, Стивен Стетсон, Леви Шапиро, Даниэль Джозеф, Аарон Фрай

  • AEW Dark, Серия 07-21

    Бесплатно 4.6

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    01:06:20
    Жанры:
    Реслинг
    Место:
    Daily's Place, Джэксонвилл, Флорида
    Бойцов:
    Мясник, Мальчик из джунглей, Джон Скайлер, Эдди Кингстон, Джон Сильвер, Марко Стант, Мудрец Скотт, Дастин Роудс, Джон Моксли, Аарон Солоу, Брэндон Катлер, Лучазавр, Фуэго-дель-Соль, Мистериозо младший, Алекс Рейнольдс, KC Navarro, Рики Старкс, Лезвие, QT Маршалл, Шанна, Джон Круз, Зайчик, Рызин, Барон Блэк, Анна Джей, Тай Конти, Ник Коморото, Электростанция Хоббса, Вертвиксен, Крюк, Джейк Ст.Патрик, Рене Мишель, Эрик Джеймс

  • AEW Dark, Серия 06-21

    Бесплатно 4,625

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    01:37:13
    Жанры:
    Реслинг
    Место:
    Daily's Place, Джэксонвилл, Флорида
    Бойцов:
    Джои Джанела, Брайан Кейдж, Ивелисс, Джек Эванс, PAC, Алекс Грация, Марко Стант, Дастин Роудс, Нила Роуз, Анджелико, Аарон Солоу, SCU, Сонни Кисс, Большой Свол, Миранда Ализе "СУПЕРСТАР", KC Navarro, Питер Авалон "Библиотекарь", QT Маршалл, Диаманте, Шон Дин, Ли Джонсон, Красный вельвет, Барон Блэк, Вики Герреро, Анна Джей, Тай Конти, Цезарь Бонони, Ник Коморото, ВСК, Вари Моралес, Крюк, Джейк Ст.Патрик, Райан Немет, Карли Браво

  • AEW Dark, Серия 05-21

    Бесплатно 4,8571

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    01:51:42
    Жанры:
    Реслинг
    Место:
    Daily's Place, Джэксонвилл, Флорида
    Бойцов:
    Джои Джанела, Рей Феникс, Ивелисс, Громовая Роза, Джон Скайлер, Алекс Грация, Сантана, Ортис, Дастин Роудс, ДокторБритт Бейкер, Дэнни Лаймлайт, Майк Верна, Аарон Солоу, Сонни Кисс, Фуэго-дель-Соль, Остин Ганн, Каталина Перес, KC Navarro, Рики Старкс, Питер Авалон "Библиотекарь", QT Маршалл, Диаманте, Лейла Хирш, Шон Дин, Дани Джордин, Красный вельвет, М’Баду, Рызин, Барон Блэк, Тай Конти, Ник Коморото, Теша Прайс, Рэй Джаз, Джазмин Аллюр, Терренс, Террелл Хьюз, Вертвиксен, Вары Моралес

  • AEW Dark, Серия 52-20

    Бесплатно 4,7273

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    01:56:11
    Жанры:
    Реслинг
    Место:
    Daily's Place, Джэксонвилл, Флорида
    Бойцов:
    Кольт Кабана, Мэтт Сидал, Рей Феникс, Мальчик из джунглей, Громовая Роза, Алекс Грация, Марко Стант, Нила Роуз, Дэнни Лаймлайт, Майк Верна, Билли Ганн, Аарон Солоу, Кип Сабиан, Лучазавр, Сонни Кисс, Фуэго-дель-Соль, Остин Ганн, Серпентико, Питер Авалон "Библиотекарь", Зло Уно, Стю Грейсон, QT Маршалл, Лютер, Лейла Хирш, Ли Джонсон, Килинн Кинг, Красный вельвет, Вики Герреро, Теша Прайс, Рэй Джаз, Мади Вренковски, Джазмин Аллюр, Терренс, Террелл Хьюз, Vertvixen

  • AEW: Динамит, Серия 46-20

    PPV AEW Plus 4.8795

    Канал:
    Вся элитная борьба
    Время эфира:
    Продолжительность:
    02:00:21
    Жанры:
    Реслинг
    Бойцов:
    Крис Джерико, Мясник, Пентагон-младший, Пента Эль Зером М, Рей Феникс, MJF, Дастин Роудс, Лезвие, QT Маршалл, Красный вельвет, Тай Конти

Как реализовать push-потоки по сети, например, в прямом эфире?

Привет,

Я разрабатываю клиент для видеосервера (VDR) с Qt 4.4 с использованием фононного каркаса.

Phonon может использовать различные типы медиаисточников, одним из которых является QIODevice. Поскольку VDR / Vomp использует настраиваемый сетевой протокол передачи данных, мне нужно переопределить поток данных самостоятельно.

Вполне понятно, как наследовать от QIODevice, если у меня есть pull-mode:
Phonon-BE запрашивает данные, они поступают в QIODevice, и я реализую readData (...) соответственно, который запрашивает данные, например, от QTcpSocket, например, в случае файл передается клиенту. Я называю это вытяжным потоком.

Теперь я тоже хочу live-tv в приложении - это push-поток, данные просто идут по сети.
Здесь я застрял в том, как это сделать правильно, поскольку QIODevice имеет некоторый документ, который в основном необходимо сделать, но на самом деле нет никакой прямой поддержки (пока AFAIHS).
Мне нужно переопределить - когда я испускаю readyRead-Signal - функцию waitForReadyRead - а также readData (). Понятно, как начать стрим, как и как его закончить.

Что я понял до сих пор:
Теперь мне нужно буферизовать данные из живого потока, затем испустить сигнал readyRead, а затем позволить IODevice прочитать из моего буфера с помощью readData.В промежутке waitForReadyRead должен выдавать условие ожидания, пока не будут получены некоторые данные.

Я пока прав?

Теперь подробные вопросы с моей стороны:
Является ли QIODevice правильным классом для использования, поскольку он не имеет встроенной поддержки непосредственно для потоков?
QBuffer не кажется правильным, поскольку у него просто будет увеличивающийся буфер и другие классы, которых я не нашел.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *