الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

كيفية ايقاف Qthread في بايثون

بدأه محمد محمود يوسف في 11 نوفمبر 2014 · 10 رد · 977 مشاهدة · في لغة Python
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته

 

عندي برنامج له واجهة رسومية يشبه الي حد كبير متصفح انترنت متعدد الالسنة وكل تبويب جديد يفتح اقوم بفتحه داخل QThread منفصل حيث يقوم كل thread بالدخول في حلقة تكرارية طويلة تصل الي ساعات وبالتالي اريد ان يستطيع المستخدم بايقاف ايا من ال threads في اي وقت

حتي الان كل شيء تم انجازه الا امكانية ايقاف الحلقة التكرارية مع العلم بان الحلقة التكرارية تقوم بتحديث الواجهة

الكود اسفله تقوم فكرته علي الاتي :

دالة اسمها campaign_loop في الفورم الرئيسي وفيها الحلقة التكرارية

كلاس موروثة من Qthread وبها دالة run تم فيها فقط عمل emit ل signal سميتها loop

في كل مرة يضغط المستخدم علي زر start يقوم البرنامج باخذ قيم الكنترولز من الفورم وتمريرها الي الدالة campaign_loop ثم يبدأ ال thread عن طريق انه يقوم بتعريف متغير جديد لل thread ويقوم بتشغيله واضافة تاب جديد مع زر ايقاف

في زر الايقاف يتم ربطه بدالة فيها جملة واحدة وهي ايقاف الthread باستخدام terminate

 

الكود مجرد مثال فقط

class Main(QMainWindow):
    def btStart(self):
        self.mythread = BrowserThread()
        self.connect(self.mythread, SIGNAL('loop()'), self.campaign_loop, Qt.AutoConnection)
        self.mythread.start()

    def btStop(self):
        self.mythread.terminate()

    def campaign_loop(self):
        loop goes here

class BrowserThread(QThread):
    def __init__(self):
        QThread.__init__(self)

    def run(self):
        self.emit(SIGNAL('loop()'))

اشكركم علي تعاونكم

لا اله الا الله عليها نحيا وعليها نموت وفي سبيلها نجاهد

#2

هل المشكلة غير واضحة ؟

لا اله الا الله عليها نحيا وعليها نموت وفي سبيلها نجاهد

#3

ألقي نظرة هنا


1

Untitled-18.jpg

#4
عامر الشابي كتب:

 

ألقي نظرة هنا

 

اشكرك اخي علي التفاعل

قمت بتجربة الطريقة التي قالها صاحب السؤال في التعليقات الا انها لم تفلح للاسف

لا اله الا الله عليها نحيا وعليها نموت وفي سبيلها نجاهد

#5

إن كنت تستخدم PyQt فإطلع على الموضوع التالي هنا


 


لم اخض تجربة في هذا من قبل لهذا جل ما استطيع هو مساعدتك بالمصادر


تم تعديل هذه المشاركة بواسطة عامر الشابي في 11 نوفمبر 2014 في 23:26

Untitled-18.jpg

#6
عامر الشابي كتب:

 

إن كنت تستخدم PyQt فإطلع على الموضوع التالي هنا

 

لم اخض تجربة في هذا من قبل لهذا جل ما استطيع هو مساعدتك بالمصادر

 

 

جزاك الله خيرا علي اهتمامك ومساعدتك لكن للاسف لا يوجد ما يساعد في هذه الاسئلة

اشكرك علي وقتك واهتمامك وكل ما اطلب من حضرتك اذا كان هناك من تتوسم فيه القدرة علي حل المشكلة ان تقوم بدعوته لزيارة الموضوع ومحاولة الافادة

 

جزاك الله خيرا

لا اله الا الله عليها نحيا وعليها نموت وفي سبيلها نجاهد

#7

ماذا تريد من Qthread بالظبط اين تكمن مشكلتك


Untitled-18.jpg

#8

اريد ايقافها فقط ، وان كان الكود فوق مش واضح فلو فيه مثال علي qthread بتشغل لووب طويل وبيحدث الواجهة اثناء تشغيله وامكانية ايقافها

تم تعديل هذه المشاركة بواسطة محمد محمود يوسف في 12 نوفمبر 2014 في 01:22

لا اله الا الله عليها نحيا وعليها نموت وفي سبيلها نجاهد

#9

في البداية احب اشكر الاخ عامر الشابي علي اهتمامه ورده والحقيقة المصادر التي اضافها كان لها عظيم الاثر في وصولي الي حل للمشكلة التي ارقتني كثيرا

 

بعد العديد من التجارب وعمليات البحث وجدت الاتي :

الكود الخاص بايقاف ال qthread باستخدام terminate يقوم بايقاف الحلقة التكرارية الموجودة في دالة run بمعني انه لا يقوم بايقاف ال thread ايا كان الكود المتاح انما يقوم بايقاف الحلقة التكرارية في run فقط ولكي استطيع تحديث الواجهة من الكلاس الرئيسية وليس من ال qthread كان يجب ان اقوم بصنع حلقة تكرارية بداخلها emit ل signal اقوم بتعريفها مسبقا والكود اسفله يوضح الفكرة

الشيء الثاني ان هذا الكود لا يعمل في لينكس انما يعمل في ويندوز فقط ولازلت لا اعرف كيف اقوم بنفس العمل في لينكس وذلك لاختلاف استجابة كل نظام لطلب ايقاف العملية الفرعية

import sys
import time
from PySide.QtGui import *
from PySide.QtCore import *

class frmMain(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.btStart = QPushButton('Start')
        self.btStop = QPushButton('Stop')
        self.counter = QSpinBox()
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.btStart)
        self.layout.addWidget(self.btStop)
        self.layout.addWidget(self.counter)
        self.setLayout(self.layout)
        self.btStart.clicked.connect(self.start_thread)
        self.btStop.clicked.connect(self.stop_thread)

    def stop_thread(self):
        self.th.stop()

    def loopfunction(self, x):
        self.counter.setValue(x)

    def start_thread(self):
        self.th = thread(2)
        self.th.loop.connect(self.loopfunction)
        self.th.setTerminationEnabled(True)
        self.th.start()

class thread(QThread):
    loop = Signal(object)

    def __init__(self, x):
        QThread.__init__(self)
        self.x = x

    def run(self):
        for i in range(100):
            self.x = i
            self.loop.emit(self.x)
            time.sleep(0.5)

    def stop(self):
        self.terminate()


app = QApplication(sys.argv)
win = frmMain()

win.show()
sys.exit(app.exec_())

عند تشغيل هذا الكود في ويندوز سوف يعمل جيدا لكن في لينكس سوف يعطي الخطأ التالي

This thread state must be current when releasing

برجاء من يعرف الحل في لينكس يضعه هنا حتي يكون الموضوع متكامل ويقدم حلا لكل من يواجه مشكلة مثل هذه

لا اله الا الله عليها نحيا وعليها نموت وفي سبيلها نجاهد

#10

ما نسخة البايثون التي تستخدمها في ليونكس؟


 


عليك أن تقوم بإستدعاء PyEval_InitThreads()


 


أدخل موقع بايثون وإبحث عن ما سبق ذكره


Untitled-18.jpg

#11

استخدم بايثون 3.4

سابحث

شكرا

لا اله الا الله عليها نحيا وعليها نموت وفي سبيلها نجاهد

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…