Comments 18
UFO just landed and posted this here
Честно — Tk еще как-то попробовать не удалось. Если geometry managers — это схемы расстановки элементов — то да, такое в Qt есть :) А насчет примеров — у PyQt4 там не одно приложение, но в них реально куча полезных вещей. Об этом я еще, думаю, расскажу.
В пакеты для разработки обычно включают программу QtDemo — это сборник примеров различной сложности. Там можно посмотреть исходники(C++) и увидеть как они работают.
Если будете писать топик про потоки в Qt, то советую особо выделить и рассмотреть QtConcurent, который является абстракцией над потоками и примитивами синхронизации.
отлично. но вопрос в том, какие потоки лучше использовать при смеси двух тенологий, остается открытым.
Ну, мне кажется, что GUI'шные потоки в основном как раз и предназначены для работы в тех случаях, когда интерфейс может «заморозиться», и они в данном случае более родные, нежели threading.Thread. А вообще работа с потоками в питоне — это темный лес во многих отношениях, причем я имею в виду не конкретно себя, а вообще среднестатистического программиста :) В данном случае каждый выбирает подход сам.
pyobject.ru/blog/2008/05/07/pyqt-unpythonic-gui/
Вот еще одна статья, автор при всей его склонности к Qt-стилю, тоже использует QThread. Так что вопрос и правда спорный :)
Вот еще одна статья, автор при всей его склонности к Qt-стилю, тоже использует QThread. Так что вопрос и правда спорный :)
Создавать отдельные потоки, чтобы в цикле не зависал GUI — это несколько странно, ведь нужно всего лишь обработать накопившуюся очередь событий, а для этого есть processEvents()
Позвольте добавить свои пять копеек:
1. Писать собственный Logger непрактично. Лучше использовать встроенные возможности Qt (qDebug) или Python (logging). И для того и для другого можно определить обработчики сообщений (Qt — qInstallMsgHandler, Python — logging.handlers).
2. Для потоков лучше написать декоратор, который будет производить всю работу по инициализации и очищению ресурсов. Это вам сильно упростит жизнь — фактически, вы сможете превращать функции из однопоточных в многопоточные, просто приписав к ним этот декоратор. Конечно, при этом они станут асинхронными, но для GUI-приложений зачастую это именно то, что нужно.
1. Писать собственный Logger непрактично. Лучше использовать встроенные возможности Qt (qDebug) или Python (logging). И для того и для другого можно определить обработчики сообщений (Qt — qInstallMsgHandler, Python — logging.handlers).
2. Для потоков лучше написать декоратор, который будет производить всю работу по инициализации и очищению ресурсов. Это вам сильно упростит жизнь — фактически, вы сможете превращать функции из однопоточных в многопоточные, просто приписав к ним этот декоратор. Конечно, при этом они станут асинхронными, но для GUI-приложений зачастую это именно то, что нужно.
Спасибо за вторую статью цикла.
С ходу отмечу небольшой просчет — когда вы показываете концепцию логирования в QTextEdit (второй листинг в этой статье), то показывайте именно концепцию.
Приведенная довольно страшненькая конструкция для перевода выводимого текста будет бесполезна в 99% случаев.
Согласен, что от нее может быть иногда толк, но она явно не относится к необходимому для логирования на форму, а перегрузка ненужными деталями затрудняет восприятие примера. К тому же неопытный читатель может так бездумно и вставить все это дело себе в код, так и не поняв что это и зачем оно на самом деле надо.
Второе, что хотел бы я отметить: то, что вы пишете — это хорошо и правильно, но только для малых (и с большой натяжкой — для средних) приложений.
Для средних же и крупных необходимо отделение логики от представления. В идеале, вся работа с Qt должна быть изолирована либо в модуле gui, либо в package с таким или подобным именем.
Ядро же программы желательно должно оставаться девственно чистым от Qt-кода (в том числе Qt-потоков):
— Это облегчит тестирование (для того, чтобы провести юнит-тестирование Qt-потока, надо инициализировать QApplication, а для некоторых других вещей — создавать главное окно).
— Это позволит снизить сложность ядра программы: разработчику ядра не обязательно держать в голове все требования и особенности Qt-реализаций.
— Это позволит легко тестировать программу в консольном режиме.
— И, наконец, это позволит держать код в едином стиле, не перемешивая методы с подчеркрутыми_именами (питон-стиль) с теми, что написалы в camelCase, не перемешивая u'Строки в юникоде' с QString-ами.
С ходу отмечу небольшой просчет — когда вы показываете концепцию логирования в QTextEdit (второй листинг в этой статье), то показывайте именно концепцию.
Приведенная довольно страшненькая конструкция для перевода выводимого текста будет бесполезна в 99% случаев.
trstring = QtGui.QApplication.translate("MainWindow", string.strip(), None, QtGui.QApplication.UnicodeUTF8)
Согласен, что от нее может быть иногда толк, но она явно не относится к необходимому для логирования на форму, а перегрузка ненужными деталями затрудняет восприятие примера. К тому же неопытный читатель может так бездумно и вставить все это дело себе в код, так и не поняв что это и зачем оно на самом деле надо.
Второе, что хотел бы я отметить: то, что вы пишете — это хорошо и правильно, но только для малых (и с большой натяжкой — для средних) приложений.
Для средних же и крупных необходимо отделение логики от представления. В идеале, вся работа с Qt должна быть изолирована либо в модуле gui, либо в package с таким или подобным именем.
Ядро же программы желательно должно оставаться девственно чистым от Qt-кода (в том числе Qt-потоков):
— Это облегчит тестирование (для того, чтобы провести юнит-тестирование Qt-потока, надо инициализировать QApplication, а для некоторых других вещей — создавать главное окно).
— Это позволит снизить сложность ядра программы: разработчику ядра не обязательно держать в голове все требования и особенности Qt-реализаций.
— Это позволит легко тестировать программу в консольном режиме.
— И, наконец, это позволит держать код в едином стиле, не перемешивая методы с подчеркрутыми_именами (питон-стиль) с теми, что написалы в camelCase, не перемешивая u'Строки в юникоде' с QString-ами.
почему использовали QThread, а не родные питоновские thread.Thread?
я не питонист и не знаю что умеет питоновский поток, но я почему-то уверен что при их использовании вы поимеете большой гемор, когда вам будут нужны сигналы и слоты в классе потока с исполнением евентЛупа внутри этого потока.
сомнительно, доверять потоки gui библиотеке.
Нет, не поимеете. Сигналы и слоты это не просто вызов функций, а целый механизм, включающий в себя как прямой вызов слотов, так и отложенный.
Вот что написано в этом в документации Qt:
Последний вариант используется в Qt по умолчанию. Работоспособность этого дела с нативными питон-нитями была мною уже не раз проверена и активно используется в разработке.
Вот что написано в этом в документации Qt:
enum Qt::ConnectionType
This enum describes the types of connection that can be used between signals and slots. In particular, it determines whether a particular signal is delivered to a slot immediately or queued for delivery at a later time.
Qt::DirectConnection — When emitted, the signal is immediately delivered to the slot.
Qt::QueuedConnection — When emitted, the signal is queued until the event loop is able to deliver it to the slot.
Qt::AutoConnection — If the signal is emitted from the thread in which the receiving object lives, the slot is invoked directly, as with Qt::DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection.
Последний вариант используется в Qt по умолчанию. Работоспособность этого дела с нативными питон-нитями была мною уже не раз проверена и активно используется в разработке.
Sign up to leave a comment.
Разговариваем про PyQt4 — Посиделка вторая