2011-01-07 37 views
9

Có ai đã sử dụng PyQt với gevent không? Làm thế nào để liên kết vòng lặp PyQt với gevent?Sử dụng PyQt với gevent

http://www.gevent.org/ - thư viện mạng Python dựa trên coroutine sử dụng greenlet để cung cấp API đồng bộ cao cấp ở đầu vòng lặp sự kiện không thích hợp.

+0

"Gevent" là gì? Vui lòng thêm liên kết cho câu hỏi của bạn. –

+0

http://www.gevent.org/ - thư viện mạng Python dựa trên coroutine sử dụng greenlet để cung cấp API đồng bộ cao cấp ở đầu vòng lặp sự kiện không thích hợp. –

+0

rất thú vị .. bạn sẽ làm gì khi pyqt + gevent hoạt động? – linjunhalida

Trả lời

2

Đây là cách bạn có thể thay đổi PyQt bởi session1 dụ của hợp tác: https://github.com/traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a

+2

Nó có thể dễ dàng dẫn đến tải CPU 100% mà không có bất kỳ hoạt động hữu ích nào, vì bạn không sử dụng khoảng thời gian 'gevent.sleep' lớn hơn 0. – fviktor

+0

Chạy vòng lặp sự kiện Qt trong một greenlet không hoạt động tốt, tôi gặp phải lỗi seg và nó chặn khi mở hộp thoại phương thức. – mguijarr

4

Bạn có thể sử dụng một IDLE Qt "hẹn giờ" để cho phép gevent chế biến microthreads của nó trong khi có sự kiện nào Qt xử lý cho một khoảng thời gian ngắn, cho ví dụ 10 mili giây. Nó vẫn chưa hoàn hảo, vì nó không tạo ra sự tích hợp tốt nhất có thể. Đó là bởi vì chúng tôi không sử dụng một vòng lặp sự kiện duy nhất cho cả Qt và gevent, chỉ cần "xen kẽ" chúng trong thời gian.

Giải pháp chính xác sẽ cho phép không muốn nghe các sự kiện Qt mới bằng cách nào đó, nhưng tôi chưa thể tìm ra cách thực hiện điều đó trong thực tế. Có thể có Qt để gửi một cái gì đó để gevent thông qua một ổ cắm khi một sự kiện GUI đến hàng đợi sự kiện sẽ giúp đỡ. Có ai đã giải quyết điều đó không?

dụ làm việc:

""" Qt - gevent event loop integration using a Qt IDLE timer 
""" 

import sys, itertools 

import PySide 
from PySide import QtCore, QtGui 

import gevent 

# Limit the IDLE handler's frequency while still allow for gevent 
# to trigger a microthread anytime 
IDLE_PERIOD = 0.01 

class MainWindow(QtGui.QMainWindow): 

    def __init__(self, application): 

     QtGui.QMainWindow.__init__(self) 

     self.application = application 

     self.counter = itertools.count() 

     self.resize(400, 100) 
     self.setWindowTitle(u'Counting: -') 

     self.button = QtGui.QPushButton(self) 
     self.button.setText(u'Reset') 
     self.button.clicked.connect(self.reset_counter) 

     self.show() 

    def counter_loop(self): 

     while self.isVisible(): 
      self.setWindowTitle(u'Counting: %d' % self.counter.next()) 
      gevent.sleep(0.1) 

    def reset_counter(self): 

     self.counter = itertools.count() 

    def run_application(self): 

     # IDLE timer: on_idle is called whenever no Qt events left for processing 
     self.timer = QtCore.QTimer() 
     self.timer.timeout.connect(self.on_idle) 
     self.timer.start(0) 

     # Start counter 
     gevent.spawn(self.counter_loop) 

     # Start you application normally, but ensure that you stop the timer 
     try: 
      self.application.exec_() 
     finally: 
      self.timer.stop() 

    def on_idle(self): 

     # Cooperative yield, allow gevent to monitor file handles via libevent 
     gevent.sleep(IDLE_PERIOD) 

def main(): 

    application = QtGui.QApplication(sys.argv) 
    main_window = MainWindow(application) 
    main_window.run_application() 

if __name__ == '__main__': 
    main() 
1

tôi phát hành một dự án có tên eventlet-pyqt. Tôi hy vọng nó có thể hữu ích cho người muốn sử dụng greenlet trong ứng dụng PyQt của họ. Tôi cũng đã cố gắng gevent, nhưng nó là khó khăn cho tôi để viết một plugin cho libevent vì kinh nghiệm ngôn ngữ C nghèo của tôi. Vấn đề chính khi sử dụng QApplicaton::processEvents() hoặc một khoảng thời gianlà, chương trình chạy vào vòng lặp vô hạn, gây ra việc sử dụng lõi CPU 100%. Để tránh điều này, tôi đã viết một trung tâm mới để thay thế chức năng select() bằng số QSocketNotifier của PyQt. Hy vọng thông điệp này có thể giúp một số.

2

Tôi đã thử cách tiếp cận sau: để có "phụ trợ PyQt" cho gevent, tức là. việc thực hiện vòng lặp gevent sử dụng các cấu trúc PyQt như QSocketNotifier, QTimer, vv thay vì vòng lặp libev. Cuối cùng tôi thấy nó dễ dàng hơn nhiều so với làm ngược lại, và hiệu năng là rất tốt (vòng lặp của Qt dựa trên glib trong Linux, nó không quá tệ).

Dưới đây là liên kết để dự án trên github cho những người quan tâm: https://github.com/mguijarr/qtgevent

Đây chỉ là một sự khởi đầu, nhưng nó hoạt động tốt cho các bài kiểm tra tôi đã làm. Tôi sẽ rất vui nếu những người có nhiều kinh nghiệm hơn với gevent và PyQt có thể đóng góp.

+0

Điều này đang làm việc cho tôi ra khỏi hộp, cảm ơn người đàn ông! – Lepi

Các vấn đề liên quan