2016-06-07 48 views
5

Tôi đang tạo một ứng dụng GUI đơn giản bằng PyQt5, nơi tôi yêu cầu một số dữ liệu từ một API mà sau đó được sử dụng để điền các điều khiển khác nhau của giao diện người dùng.Chuỗi công nhân đơn lẻ cho tất cả công việc hoặc nhiều công nhân cụ thể?

Các ví dụ tôi đã theo dõi về các chuỗi công việc trong PyQt tất cả dường như là phân lớp QThread và sau đó thực hiện logic nghiệp vụ của họ theo phương pháp bị ghi đè run(). Điều này hoạt động tốt nhưng tôi muốn thực hiện các cuộc gọi API khác nhau vào các thời điểm khác nhau bằng cách sử dụng một nhân viên. Vì vậy, câu hỏi của tôi là: tôi có cần tạo một chuỗi công nhân cụ thể cho mọi hoạt động tôi muốn làm hay có cách để có một lớp chuỗi đơn lẻ mà tôi có thể sử dụng để thực hiện các hoạt động khác nhau tại các thời điểm khác nhau và do đó tránh các chi phí của việc tạo ra các tiểu học chủ đề khác nhau?

+2

Bạn không nên phân lớp 'QThread'. Thay vào đó, hãy sử dụng 'QtConcurrent :: run', hoặc có lẽ là phân lớp' QObject' và di chuyển các đối tượng công nhân này vào một chuỗi công nhân đơn lẻ. –

Trả lời

6

Những gì bạn có thể làm là thiết kế một đối tượng để thực hiện tất cả các tác vụ này (kế thừa QObject cho vị trí/tín hiệu). Giả sử mỗi tác vụ được định nghĩa là một hàm riêng biệt - cho phép chỉ định các hàm này làm các vùng.

Sau đó (một trật tự chung của các sự kiện):

  • tạo một đối tượng QThread.
  • khởi tạo lớp học của bạn.
  • Chuyển đối tượng của bạn vào chủ đề bằng cách sử dụng YouClass->moveToThread(pThread).
  • Bây giờ, hãy xác định tín hiệu cho từng vị trí và kết nối các tín hiệu này với các vị trí phù hợp trong đối tượng của bạn.
  • Cuối cùng chạy thread sử dụng pThread->start()

Bây giờ bạn có thể phát ra một tín hiệu để làm một nhiệm vụ cụ thể trong các chủ đề. Bạn không cần phải phụ QThread chỉ cần sử dụng một lớp bình thường có nguồn gốc từ QObject (để bạn có thể sử dụng khe/tín hiệu).

Bạn có thể sử dụng một lớp trong một chuỗi để thực hiện nhiều thao tác (lưu ý: chúng sẽ được xếp hàng đợi). Hoặc tạo nhiều lớp trong nhiều luồng (để chạy "song song").

Tôi không biết python cũng đủ để cố gắng một ví dụ ở đây vì vậy tôi sẽ không: o

Lưu ý: Lý do để sub-class QThread sẽ được nếu bạn muốn mở rộng chức năng của Lớp QThread - tức là thêm các hàm liên quan đến chuỗi/cụ thể hơn. QThread là một lớp điều khiển một luồng, và không có nghĩa là được sử dụng để chạy các nhiệm vụ tùy ý/chung chung ... mặc dù bạn có thể lạm dụng nó nếu bạn muốn :)

+0

Câu trả lời xuất sắc, đặc biệt là họ gợi ý rằng các công việc sẽ tự động được xếp hàng đợi. Có lẽ tôi sẽ viết một ví dụ cho điều đó. – Trilarion

+0

@Xin cảm ơn, và có, vui lòng thêm ví dụ:) –

3

Đây là một ví dụ ngắn gọn của một (nhưng có thể là nhiều như bạn muốn) đối tượng công nhân được chuyển đến một QThread chạy (bắt đầu) và đang giao tiếp thông qua tín hiệu. Ngoài ra thread được dừng lại ở cuối. Nó thể hiện code_fodder được nêu trong his answer.

from PyQt4 import QtCore 
QtCore.Signal = QtCore.pyqtSignal 

class Master(QtCore.QObject): 

    command = QtCore.Signal(str) 

    def __init__(self): 
     super().__init__() 

class Worker(QtCore.QObject): 

    def __init__(self): 
     super().__init__() 

    def do_something(self, text): 
     print('current thread id = {}, message to worker = {}'.format(int(QtCore.QThread.currentThreadId()), text)) 

if __name__ == '__main__': 

    app = QtCore.QCoreApplication([]) 

    # give us a thread and start it 
    thread = QtCore.QThread() 
    thread.start() 

    # create a worker and move it to our extra thread 
    worker = Worker() 
    worker.moveToThread(thread) 

    # create a master object and connect it to the worker 
    master = Master() 
    master.command.connect(worker.do_something) 

    # call a method of the worker directly (will be executed in the actual thread) 
    worker.do_something('wrong way to communicate with worker') 

    # communicate via signals, will execute the method now in the extra thread 
    master.command.emit('right way to communicate with worker') 

    # start the application and kill it after 1 second 
    QtCore.QTimer.singleShot(1000, app.quit) 
    app.exec_() 

    # don't forget to terminate the extra thread 
    thread.quit() 
    thread.wait(5000) 
Các vấn đề liên quan