پایتون در عمق

آموزش زبان پایتون به زبان فارسی

پایتون در عمق

آموزش زبان پایتون به زبان فارسی

آموزش مقدماتی برنامه نویسی GUI با PyQt - بخش دوم

شنبه, ۱۵ اسفند ۱۳۹۴، ۱۰:۵۴ ب.ظ

چه روز خوبی برای کار با PyQt ــست :-)

در بخش قبل ( آموزش مقدماتی طراحی رابط کاربری با PyQt ) کمی آشناشدیم، 

حال با روشی منطقی ادامه میدهیم.


در بخش قبل یک اینستنس از کلاس QMainWindow ساختیم اما در دنیای واقعی این درست نیست!

ٌٌQMainWindow در واقع به عنوان فریم ورکی است برای ساختن پنجره ها. در واقع پنجره ها اینستنس هایی از فرزندان این کلاس اند. بیایید مثال بخش قبل را اصلاح کنیم:

import sys

from PyQt4 import QtGui


class myCustomWindow(QtGui.QMainWindow):
     def __init__(self):
          super(myCustomWindow,self).__init__()
          self.setWindowTitle("Python In Depth")
          window_icon = QtGui.QIcon("pythonindepth.png") # Adress file ra vared mikonim
          self.setWindowIcon(window_icon)
          self.resize(300,200) # arz va ertefa bar hasbe pixel
          self.move(400,200) # arz va tool bar hasbe pixel
     
def main():
     app = QtGui.QApplication(sys.argv)
     my_window = myCustomWindow()
     my_window.show()
    
     app.exec_()
    
if __name__ == "__main__":
    main()

کلاس سفارشی myCustomWindow ایجاد کردیم و my_window را از این کلاس جدید ایجاد کردیم. تنظیمات پنجره را هم به __init__ کلاس جدیدمان منتقل کردیم.


حال چگونه به برنامه خود دکمه ، منو ، نوشته ، جدول و ... اضافه کنیم؟

بسیار خوب! پای کیوتی (PyQt) همه اینها را با عنوان Widget میشناسد! در نمودار زیر ویدجت های مختلف را میبینیم که همگی فرزندی از کلاس QWidget اند :

برای استفاده از این ویدجت ها لازم است از کلاسشان اینستنس بسازیم.

جهت خوانایی بهتر کد، این ویدجت ها را در متدی با نام createWidget در کلاس myCustomWindow وارد کنیم:

def createWidgets(self):
          self.label = QtGui.QLabel("Esmetun?") # anche ke mikhahim in widget nemayesh dahadra be onvan parametr midahim
          self.lineEdit = QtGui.QLineEdit()
          self.button = QtGui.QPushButton("Vurud")

  اما این کافی نیست! باید نحوه چینش ویدجت ها را هم مشخص کنیم!

برای این منظور باید میان طراحی ایستا(ثابت) یا طراحی پویا (relative - وابسته - Dynamic) یکی را برگزینیم.

برای اطلاعات بیشتر مراجعه کنید به [ بعدا تکمیل خواهد شد ]


برای طراحی دینامیکی میتوانیم از کلاس های QHBoxLayout یا QVBoxLayout یا QGridLayout ویا QFormLayout استفاده کنیم.
برای مثال:

  • QHBoxLayout : ویدجت ها را به طور افقی میچیند.
  • QVBoxLayout : ویدجت ها را به طور عمودی میچیند.
در بخش های بعد بیشتر با نحوه Layout بندی آشنا خواهیم شد.
فی الحال از QHBoxLayout برای چینش افقی ویدجت هایی که ساخته بودیم استفاده میکنیم، به این شکل که:
          h_box = QtGui.QHBoxLayout()
          h_box.addWidget(self.label)
          h_box.addWidget(self.lineEdit)
          h_box.addWidget(self.button)
یک اینستنس از کلاس QHBoxLayout ایجاد میکنیم و ویدجت های مورد نظر را در آن add میکنیم
حال باید h_box را به یکی از اجزای پنجره اصلی منسوب کنیم. با اینکار ویدجت های داخل آن هم نمایش داده میشوند
اجزای اصلی یک QMainWindow را بنگرید:
[در ادامه آموزش بیشتر با این اجزا آشنا خواهیم شد] Central Widget بخش اصلی پنجره را تشکیل میدهد. پس لی اوت h_box را به آن اعمال میکنیم، اما چون مستقیما اینکار ممکن نیست از یک متغییر دیگر استفاده میکنیم
          myCentralWidget = QtGui.QWidget()
          myCentralWidget.setLayout(h_box)
متغییر myCentralWidget را از کلاس پایه تمام ویدجت ها میسازیم. برای دسته بندی ویدجت ها هم معمولا از اینستنس این کلاس استفاده خواهیم کرد.
حال myCentralWidget را به عنوان Central Widget پنجره معرفی میکنیم:
          self.setCentralWidget(myCentralWidget)


خوب! به کلاس myCustomWindow برمیگردیم! متد __init__ ویژگی اصلی پنجره را تنظیم میکرد، متد createWidget ویدجت های مورد نیازمان را تولید میکرد. حال متد initUI را هم اضافه میکنیم تا وظیفه مدیریت چینش ویدجت ها را برعهده گیرد.
ایندو متد را در __init__ فراخوانی میکنیم.

در نهایت کد ما بدین شکل تبدیل میشود:
import sys
from PyQt4 import QtGui
class myCustomWindow(QtGui.QMainWindow):
     def __init__(self):
          super(myCustomWindow,self).__init__()
          self.setWindowTitle("Python In Depth")
          window_icon = QtGui.QIcon("pythonindepth.png") # Adress file ra vared mikonim
          self.setWindowIcon(window_icon)
          self.resize(300,200) # arz va ertefa bar hasbe pixel
          self.move(400,200) # arz va tool bar hasbe pixel
          
          self.createWidgets()
          self.initUI()
     
     def initUI(self):
          h_box = QtGui.QHBoxLayout()
          h_box.addWidget(self.label)
          h_box.addWidget(self.lineEdit)
          h_box.addWidget(self.button)
          myCentralWidget = QtGui.QWidget()
          myCentralWidget.setLayout(h_box)
          
          self.setCentralWidget(myCentralWidget)
          
     def createWidgets(self):
          self.label = QtGui.QLabel("Esmetun?")
          self.lineEdit = QtGui.QLineEdit()
          self.button = QtGui.QPushButton("Vurud")
          
          
          
def main():
     app = QtGui.QApplication(sys.argv)
     my_window = myCustomWindow()
     my_window.show()
    
     app.exec_()
    
if __name__ == "__main__":
    main()
و در نهایت خروجی کد ما:

در بخش بعد با signal & slot آشنا میشویم. هیجان انگیز است :-)

موافقین ۰ مخالفین ۰ ۹۴/۱۲/۱۵
محسن فراهانچی

نظرات  (۲)

لطفا ادامه بدین
پاسخ:
چشم انشالله این وبلاگ رو در قالب یک سایت ادامه میدم

ممنونم
۱۳ تیر ۹۶ ، ۰۸:۵۴ محمداسماعیل
لایکا کثیرا
کاش ادامه میدادی
پاسخ:
حقیقتا فرصتی که در اختیار داشتم قبلا رو هدر دادم و کم کاری کردم و آموزش ها رو کامل نکردم. الان هم فرصتم خیلی گرفته است و کارای بزرگتری باید انجام بدم. 
هر چند من در خدمتتون هستم و هر کی هر سوال و هر راهنمایی میخواد بی چشم داشت در خدمتش هستم. 
حتی واقعا عالی میشه که کسی پایه باشه من بهش یاد بدم بعد این آموزش ها رو تکمیل کنه. 

ارادمتند 
mohsenfarahanchi [at] outlook دات کام

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی