انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید


توزیع گنو/لینوکس اوبونتو ۲۰ ساله شد 🎉

نویسنده موضوع: timer در پایتون چه جوریه ؟  (دفعات بازدید: 6591 بار)

0 کاربر و 1 مهمان درحال مشاهده موضوع.

آفلاین moshen212

  • Sr. Member
  • *
  • ارسال: 344
  • جنسیت : پسر
timer در پایتون چه جوریه ؟
« : 12 بهمن 1387، 09:36 ق‌ظ »
سلام
من میخوام مثلا هر ۵ ثانیه یک کار رو انجام بدم واسه همین نیاز به تایمر دارم ولی نمیدونم تایمر رو کجا و چجوری باید استفاده کنم و اصلا در کدوم کتابخانه هست کمکم کنید لطفا ؟
ممنونم

آفلاین Bayazee

  • Jr. Member
  • *
  • ارسال: 91
    • آموزش زبان برنامه نویسی پایتون
پاسخ به: timer در پایتون چه جوریه ؟
« پاسخ #1 : 12 بهمن 1387، 01:45 ب‌ظ »
سلام
احتمالا این کار رو توسط thread انجام می دید. کافی هست هر بار زمان رو با استفاده از time.time یک جایی ذخیره کنید و هر وقت مثلا تفاضل این زمان ذخیره شده و زمان فعلی ۵ ثانیه شد کار خاصی رو انجام بدید ...
آموزش زبان برنامه نویسی پایتون (Python) در وب سایت ! www.pythoni.ca

آفلاین moshen212

  • Sr. Member
  • *
  • ارسال: 344
  • جنسیت : پسر
پاسخ به: timer در پایتون چه جوریه ؟
« پاسخ #2 : 13 بهمن 1387، 09:26 ق‌ظ »
سلام
نقل‌قول
احتمالا این کار رو توسط thread انجام می دید. کافی هست هر بار زمان رو با استفاده از time.time یک جایی ذخیره کنید و هر وقت مثلا تفاضل این زمان ذخیره شده و زمان فعلی ۵ ثانیه شد کار خاصی رو انجام بدید ...
ها اییییییی thread که وگفتی یعنی چه ؟

آفلاین ashkan

  • Newbie
  • *
  • ارسال: 10

آفلاین سعید رسولی

  • ilius, saeedgnu
  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 1543
  • جنسیت : پسر
پاسخ به: timer در پایتون چه جوریه ؟
« پاسخ #4 : 13 بهمن 1387، 02:41 ب‌ظ »
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys, time, thread

def my_func(marker, num):
  for i in range(num):
    back = '\b'*(len(marker)+1)
    print '%s%s%s'%(back, marker,' '*len(marker)),
    sys.stdout.flush()
    time.sleep(0.1)


def method1():
  while True:
    thread.start_new_thread(my_func, (u'█',10))
    print
    time.sleep(5.0)

def method2():
  t0 = time.time()
  next_time=0.0
  while True:
    t = time.time() - t0
    if t > next_time:
      thread.start_new_thread(my_func, ('()',10))
      print
      next_time += 5.0
    time.sleep(0.01)

print 'Method 1, Press Ctrl+C to stop...'
try:
  method1()
except KeyboardInterrupt:
  print 'Canceled'

print 'Method 2, Press Ctrl+C to stop...'
try:
  method2()
except KeyboardInterrupt:
  print 'Canceled'

آفلاین moshen212

  • Sr. Member
  • *
  • ارسال: 344
  • جنسیت : پسر
پاسخ به: timer در پایتون چه جوریه ؟
« پاسخ #5 : 15 بهمن 1387، 08:51 ق‌ظ »
سلام
اینی که نوشتی باحاله ولی نمیدونم چه جوریه ؟ تو برنامه نویسی gtk کار نداد. مشکل من این هست که دکمه رو که فشار میدم میخوام در زمان فشرده شدنش هر 0.1 ثانیه یک کاری انجام بده و با رها کردنش متوقف شه قسمت اول رو مشکلی نداره ولی در زمان رها کردن این رویداد رو نادیده میگیره واسه همین وارد حلقه ی بینهایت میشه.  ](*,)

آفلاین سعید رسولی

  • ilius, saeedgnu
  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 1543
  • جنسیت : پسر
پاسخ به: timer در پایتون چه جوریه ؟
« پاسخ #6 : 15 بهمن 1387، 06:02 ب‌ظ »
سلام
اینی که نوشتی باحاله ولی نمیدونم چه جوریه ؟ تو برنامه نویسی gtk کار نداد. مشکل من این هست که دکمه رو که فشار میدم میخوام در زمان فشرده شدنش هر 0.1 ثانیه یک کاری انجام بده و با رها کردنش متوقف شه قسمت اول رو مشکلی نداره ولی در زمان رها کردن این رویداد رو نادیده میگیره واسه همین وارد حلقه ی بینهایت میشه.  ](*,)
سلام
خب زودتر می‌گفتید برای gtk می‌خواید. gtk خودش برنامه رو multi thread میکنه، اصلاً نیازی به استفاده از ماژول thread نیست.
برای این کاری که می‌خواید، باید event رها شدن دکمه رو با یه سیگنالی متناظر کنید که یه تابعی اجرا بشه و یه متغیری رو(مثلاً به اسم bottonDown) از True به False تغییر بده، و توی تابع مربوط به فشردن دکمه، توی همون حلقه‌ای که هر 0.1 ثانیه یه کاری میکنه، هر بار چک کنید که اون متغیر bottonDown درست هست یا نه، اگه False هست متوقف بشه(از تابع return کنه، یا از حلقه break کنه)

ساده‌ترین راهی که به ذهنم میرسه اینه. اگه کدتون رو بدید می‌تونم درستش کنم.

آفلاین moshen212

  • Sr. Member
  • *
  • ارسال: 344
  • جنسیت : پسر
پاسخ به: timer در پایتون چه جوریه ؟
« پاسخ #7 : 16 بهمن 1387، 08:44 ق‌ظ »
سلام مجدد
ilius جان ببین کدی که گذاشتم خیلی ساده هست قراره با زدن دکمه ی سمت راست اون label بره سمت راست و با کلید سمت چپ بره به سمت چپ.
import thread,time,pygtk
pygtk.require('2.0')
import gtk
#
stop = False
#

def xy(x,y,n):
while( not stop ):
x += n
print x
layout.move(label,x,y)
time.sleep(0.2)

def mouse_press(widget,e,n):
stop = False
xy(label.get_allocation().x,label.get_allocation().y,n)

def  mouse_release(widget,e):
stop = True

win = gtk.Window()
layout = gtk.Layout()
box = gtk.HBox()
label = gtk.Label("(0)")
btn1 = gtk.Button("<<")
btn1.connect( "button_press_event",mouse_press,-2 )
btn1.connect( "button_release_event",mouse_release )
btn2 = gtk.Button(">>")
btn2.connect( "button_press_event",mouse_press,2 )
btn1.connect( "button_release_event",mouse_release )

win.add(box)
win.connect("destroy",gtk.main_quit)
win.set_size_request(250,250)
layout.put(label,70,100)
box.pack_start(btn1,False,False,0)
box.pack_start(layout,True,True,0)
box.pack_start(btn2,False,False,0)
win.show_all()
gtk.main()

از همکاریهاتون بسیار ممنونم

آفلاین سعید رسولی

  • ilius, saeedgnu
  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 1543
  • جنسیت : پسر
پاسخ به: timer در پایتون چه جوریه ؟
« پاسخ #8 : 16 بهمن 1387، 12:08 ب‌ظ »
سلام و صد سلام.
خواهش می‌کنم.
#!/usr/bin/python
import time, pygtk
pygtk.require('2.0')
import gtk
#
stop = True
#

def xy(x,y,n):
global stop
while not stop:
x += n
#print x
layout.move(label,x,y)
      while gtk.events_pending():
        gtk.main_iteration_do(False)
time.sleep(0.2)

def mouse_press(e,n):
        global stop
stop = False
xy(label.get_allocation().x,label.get_allocation().y,n)

def mouse_release(e):
        global stop
stop = True

win = gtk.Window()
layout = gtk.Layout()
box = gtk.HBox()
label = gtk.Label("(0)")
btn1 = gtk.Button("<<")
btn1.connect( "pressed",mouse_press,-2 )
btn1.connect( "released",mouse_release )
btn2 = gtk.Button(">>")
btn2.connect( "pressed",mouse_press, 2)
btn2.connect( "released",mouse_release )

win.add(box)
win.connect("destroy",gtk.main_quit)
win.set_size_request(250,250)
layout.put(label,70,100)
box.pack_start(btn1,False,False,0)
box.pack_start(layout,True,True,0)
box.pack_start(btn2,False,False,0)
win.show_all()
gtk.main()

1- اگه میخواید از درون یک تابع، یک متغییر global رو تغییر بدید، باید اول تابع اعلام کنید(مثلا اینجا global stop در اول اون سه تا تابع)

2- علت اینکه بعد از زدن دکمهٔ سمت راست و رها کردنش، متوقف نمی‌شد(حتی بعد از رفع مشکل 1) ، این بود که موقع connect کردن دکمهٔ دومی(خط 31 برنامهٔ خودتون) اشتباهی نوشته بودید btn1 بجای btn2 پس برای رها شدن دکمهٔ دوم(سمت راست) هیچ تابعی تعیرف نشده بود.

3- علت اینکه تغییرات در رابط گرافیکی اعمال نمیشد(فقط چاپ میشد) این بود که شما توی اون حلقه(تابع xy) رابط گرافیکی رو update نمی‌کردید، با اضافه کردن این دو خط:
while gtk.events_pending():
gtk.main_iteration_do(False)
درست شد.

4- در ضمن استفاده از سیگنال pressed راحت‌تر از button_press_event هست، هم کوتاه تره، هم آرگومان اول(widget) از دو تابع mouse_press و mouse_release حذف میشه(که اینجا نیازی بهشون نیست). همینطور برای button_release_event.

5- نیازی به import کردن ماژول thread نیست. (فکر نمی‌کنم برنامه‌های gtk هیچ‌وقت به این ماژول نیاز پیدا کنن، مگه به ندرت پیش بیاد)

« آخرین ویرایش: 16 بهمن 1387، 12:12 ب‌ظ توسط ilius »

آفلاین سعید رسولی

  • ilius, saeedgnu
  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 1543
  • جنسیت : پسر
پاسخ به: پاسخ به: timer در پایتون چه جوریه ؟
« پاسخ #9 : 16 بهمن 1387، 02:36 ب‌ظ »
کدتون باحال بود. ;D یکم باهاش بازی کردم، این شد:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import time, pygtk
pygtk.require('2.0')
import gtk

speed=2
delay=0.005
width=400
height=30
w0=39
h0=10

stop=True
direc=1

def move_x(x, y):
  global stop, direc
  if direc>0:
    label.set_label(' ●>')
  elif direc<0:
    label.set_label('<●')
  while not stop:
    if x<0:
      direc=1
      label.set_label(' ●>')
    elif x>width-2*w0:
      direc = -1
      label.set_label('<●')
    x += (direc*speed)
    layout.move(label, x, y)
    while gtk.events_pending():
      gtk.main_iteration_do(False)
    time.sleep(delay)

def mouse_press(e, d):
  global stop, direc
  stop = False
  direc = d
  move_x(label.get_allocation().x, label.get_allocation().y)
 
def mouse_release(e):
  global stop
  stop = True
  label.set_label(' ● ')

win = gtk.Window()
layout = gtk.Layout()
box = gtk.HBox()
label = gtk.Label(' ● ')
btn1 = gtk.Button('<<')
btn1.connect( 'pressed', mouse_press, -1)
btn1.connect( 'released', mouse_release )
btn2 = gtk.Button('>>')
btn2.connect( 'pressed', mouse_press, 1)
btn2.connect( 'released', mouse_release )

win.add(box)
win.connect('destroy', gtk.main_quit)
win.set_size_request(width, height)
layout.put(label, width/2-w0, height/2-h0)
box.pack_start(btn1, False, False, 0)
box.pack_start(layout, True, True, 0)
box.pack_start(btn2, False, False, 0)
win.show_all()
gtk.main()

آفلاین moshen212

  • Sr. Member
  • *
  • ارسال: 344
  • جنسیت : پسر
پاسخ به: timer در پایتون چه جوریه ؟
« پاسخ #10 : 17 بهمن 1387، 08:03 ق‌ظ »
سلام
بابا تو دیگه کی هستی  :o
برنامه ی بسیار جالبی نوشتی البته من یک متد دیگه هم برای gtk پیدا کردم که به این صورت هست:
این متد در کتابخانه ی gobject هست
gobject.timeout_add(زمان بر حسب هزارم ثانیه , func , arg1 , arg2 , ... , argn)البته در این روش تابع فقط یکبار اجرا میشه و لی میشه توی تابع هم دوباره ازش استفاده کرد.
« آخرین ویرایش: 17 بهمن 1387، 08:11 ق‌ظ توسط moshen212 »

آفلاین سعید رسولی

  • ilius, saeedgnu
  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 1543
  • جنسیت : پسر
پاسخ به: پاسخ به: timer در پایتون چه جوریه ؟
« پاسخ #11 : 17 بهمن 1387، 09:56 ق‌ظ »
سلام
(راستی میگم خوش به حالت شما خیلی صواب میبری، چون توی همهٔ ارسال‌هات سلام می‌کنی! ;D)

شما برنامه رو نوشتی، من فقط اصلاحش کردم  ;D
اون timeout_add هم جالب بود. ممنون.

آفلاین moshen212

  • Sr. Member
  • *
  • ارسال: 344
  • جنسیت : پسر
پاسخ به: timer در پایتون چه جوریه ؟
« پاسخ #12 : 18 بهمن 1387، 08:26 ق‌ظ »
سلام
ممنونم از شما بخاطر همکاریهاتون ولی میشه بگی که از کجا فهمیدی باید از این کد استفاده کنی ؟
while gtk.events_pending():
gtk.main_iteration_do(False)
اگه نمی گفتید هیچ وقت نمی فهمیدم که باید از این کد استفاده کنم در ضمن بگید اصلا این events_pending و main_iteration_do کارشون چیه؟

آفلاین سعید رسولی

  • ilius, saeedgnu
  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 1543
  • جنسیت : پسر
پاسخ به: timer در پایتون چه جوریه ؟
« پاسخ #13 : 18 بهمن 1387، 09:27 ق‌ظ »
سلام
ممنونم از شما بخاطر همکاریهاتون ولی میشه بگی که از کجا فهمیدی باید از این کد استفاده کنی ؟
while gtk.events_pending():
gtk.main_iteration_do(False)
اگه نمی گفتید هیچ وقت نمی فهمیدم که باید از این کد استفاده کنم در ضمن بگید اصلا این events_pending و main_iteration_do کارشون چیه؟
سلام
خواهش می‌کنم.
توی کد یکی از برنامه‌ها دیدم(نمی‌دونم رابط گرافیکی هما بود، یا دیکشنری سیب یا...) من چون زیاد از سورس برنامه‌های موجود استفاده می‌کنم. این update کردن پنجرهٔ gtk هم که چیز مهمی توی خیلی‌هاشون(شایدم اکثرشون) که از gtk استفاده میکنن هست. همیشه هم این دو خط رو کپی و پیست می‌کنم(حتی تایپ هم نمی‌کنم) برای همین معنای دقیقش رو نمی‌دونم، ولی کلیتش اینه که میگه تا وقتی یه event ی هست که بهش جواب ندادی، اول به اون جواب بده بعد برو سراغ بقیهٔ برنامه. وقتی لازم میشه که مدت قابل توجهی(مثلاً چند ثانیه) برنامه در یک تابع خاصی بمونه(که معمولاً در حلقه‌ها همچین اتفاقی میفته) که در این موارد باید هر چند وقت یه بار به interface برنامه‌ت برسی، وگرنه پنجره‌ش not responding میشه و تغییرات اعمال نمیشه و کاربر فکر میکنه برنامه هنگ کرده.