ساخت پلاگین پایتون (QGIS3) 

پلاگین ها یک راه عالی برای گسترش عملکرد QGIS هستند. می‌توانید با استفاده از پایتون پلاگین‌هایی بنویسید که می‌توانند از افزودن یک دکمه ساده تا جعبه‌ابزارهای پیچیده متغیر باشند. این آموزش به تشریح مراحل مربوط به راه اندازی محیط توسعه، طراحی رابط کاربری برای یک افزونه و نوشتن کد برای تعامل با QGIS می پردازد. لطفاً آموزش شروع برنامه نویسی پایتون (QGIS3) را مرور کنید تا با اصول اولیه آشنا شوید.

توجه داشته باشید

اگر در حال ساختن یک پلاگین جدید هستید، اکیداً توصیه می کنم به جای پلاگین GUI که در این آموزش توضیح داده شده است، یک افزونه پردازش بسازید. برای جزئیات بیشتر به ساخت پلاگین پردازش (QGIS3) مراجعه کنید .

مروری بر وظیفه 

ما یک پلاگین ساده به نام ایجاد خواهیم کرد که به کاربران امکان می دهد یک لایه برداری را انتخاب کنند و ویژگی های آن را در یک فایل CSV بنویسند.Save Attributes

ابزارها را دریافت کنید 

Qt Creator 

Qt یک چارچوب توسعه نرم افزار است که برای توسعه برنامه های کاربردی که بر روی ویندوز، مک، لینوکس و همچنین سیستم عامل های مختلف تلفن همراه اجرا می شوند، استفاده می شود. خود QGIS با استفاده از چارچوب Qt نوشته شده است. برای توسعه افزونه، ما از اپلیکیشنی به نام Qt Creator برای طراحی رابط برای افزونه خود استفاده خواهیم کرد.

نصب کننده Qt Creator را از Qt Offline Installers دانلود و نصب کنید . مطمئن شوید که Qt Creator را در صفحه دانلود انتخاب کرده اید. توجه داشته باشید که برای نصب بسته باید یک حساب Qt رایگان ایجاد کنید.

توجه داشته باشید

نصب کننده OSGeo4w برای QGIS در ویندوز شامل یک کپی از برنامه Qt Designer است که نسخه سبک وزن Qt Creator است و برای ساخت پلاگین ها کاملاً مناسب است. می توانید دانلود Qt Creator را نادیده بگیرید و به جای آن از C:\OSGeo4W64\bin\qgis-designer استفاده کنید .

../../_images/setup1.png

پیوندهای پایتون برای Qt 

از آنجایی که ما در حال توسعه افزونه در پایتون هستیم، باید پیوندهای پایتون را برای Qt نصب کنیم. روش نصب اینها به پلتفرمی که استفاده می کنید بستگی دارد. برای ساخت پلاگین ها به pyrcc5ابزار خط فرمان نیاز داریم .

ویندوز

پیوندهای پایتون مربوطه در نصب QGIS در ویندوز گنجانده شده است. اما برای استفاده از آنها از پوشه افزونه، باید مسیر نصب QGIS را مشخص کنیم.

یک فایل Windows Batch (پسوند bat.) با محتوای زیر ایجاد کنید و آن را در رایانه خود به عنوان ذخیره کنید compile.bat. بعداً این فایل را در پوشه افزونه کپی می کنیم. اگر QGIS را در مسیر دیگری نصب کرده اید، C:\OSGeo4W64\bin\مسیر خود را جایگزین کنید.

@echo off
call "C:\OSGeo4W64\bin\o4w_env.bat"
call "C:\OSGeo4W64\bin\qt5_env.bat"
call "C:\OSGeo4W64\bin\py3_env.bat"

@echo on
pyrcc5 -o resources.py resources.qrc

../../_images/setup2.pngمک

مدیر بسته Homebrew را نصب کنید . PyQtبا اجرای دستور زیر بسته را نصب کنید :

brew install pyqt
لینوکس
بسته به توزیع خود، python-qt5بسته را پیدا و نصب کنید. در توزیع های مبتنی بر اوبونتو و دبیان، می توانید دستور زیر را اجرا کنید:
sudo apt-get install python-qt5

توجه داشته باشید

ممکن است متوجه شوید که QGIS قبلاً این بسته را نصب کرده است.

یک ویرایشگر متن یا یک IDE پایتون 

هر نوع توسعه نرم افزاری نیاز به یک ویرایشگر متن خوب دارد. اگر قبلاً یک ویرایشگر متن مورد علاقه یا یک IDE (محیط توسعه یکپارچه) دارید، می توانید از آن برای این آموزش استفاده کنید. در غیر این صورت، هر پلتفرم طیف گسترده ای از گزینه های رایگان یا پولی را برای ویرایشگرهای متن ارائه می دهد. یکی را انتخاب کنید که متناسب با نیاز شما باشد.

این آموزش از ویرایشگر Notepad++ در ویندوز استفاده می کند.

ویندوز

Notepad++ یک ویرایشگر رایگان خوب برای ویندوز است. ویرایشگر Notepad++ را دانلود و نصب کنید .

توجه داشته باشید

اگر از Notepad++ استفاده می‌کنید، حتماً به تنظیمات ‣ تنظیمات برگزیده ‣ تنظیمات برگه بروید و جایگزینی با فاصله را فعال کنید . پایتون در مورد فضای سفید بسیار حساس است و این تنظیم باعث می شود که برگه ها و فضاها به درستی رفتار شوند.

افزونه افزونه ساز 

یک پلاگین مفید QGIS به نام وجود دارد که تمام فایل های لازم و کد دیگ بخار را برای یک پلاگین ایجاد می کند. افزونه را پیدا و نصب کنید . برای جزئیات بیشتر در مورد نحوه نصب افزونه ها به استفاده از افزونه ها مراجعه کنید .Plugin BuilderPlugin Builder

افزونه Plugins Reloader 

این افزونه کمکی دیگری است که امکان توسعه تکراری پلاگین ها را فراهم می کند. با استفاده از این افزونه، می توانید کد پلاگین خود را تغییر دهید و بدون نیاز به راه اندازی مجدد QGIS هر بار، آن را در QGIS منعکس کنید. افزونه را پیدا و نصب کنید . برای جزئیات بیشتر در مورد نحوه نصب افزونه ها به استفاده از افزونه ها مراجعه کنید .Plugin Reloader

توجه داشته باشید

Plugin Reloader یک افزونه آزمایشی است. اگر نمی توانید آن را پیدا کنید، مطمئن شوید که نمایش افزونه های آزمایشی را در تنظیمات مدیر پلاگین علامت زده اید.

  1. QGIS را باز کنید. به Plugins ‣ Plugin Builder ‣ Plugin Builder بروید .
../../_images/129.png
  1. گفتگوی QGIS Plugin Builder را با یک فرم خواهید دید . می توانید فرم را با جزئیات مربوط به افزونه ما پر کنید. نام کلاس، نام کلاس پایتون خواهد بود که حاوی منطق پلاگین است. این نام پوشه حاوی تمام فایل های افزونه نیز خواهد بود. SaveAttributesبه عنوان نام کلاس وارد کنید . نام افزونه نامی است که پلاگین شما تحت آن در مدیریت پلاگین ظاهر می شود . نام را به عنوان وارد کنید . در قسمت توضیحات توضیحات اضافه کنید . نام ماژول، نام فایل پایتون اصلی افزونه خواهد بود. آن را به عنوان وارد کنید . شماره نسخه ها را همانطور که هستند بگذارید و نام و آدرس ایمیل خود را در قسمت های مربوطه وارد کنید. روی Next کلیک کنید .Save Attributessave_attributes
../../_images/219.png
  1. توضیح مختصری از افزونه را برای گفتگوی About وارد کنید و روی Next کلیک کنید .
../../_images/317.png
  1. از انتخابگر الگو، را انتخاب کنید . مقدار آیتم Text for menu این است که چگونه کاربران افزونه شما را در منوی QGIS پیدا می کنند. آن را به عنوان وارد کنید . فیلد منو تعیین می کند که آیتم افزونه شما کجا در QGIS اضافه شود. از آنجایی که افزونه ما برای داده های برداری است، را انتخاب کنید . روی Next کلیک کنید .Tool button with dialogSave Attributes as CSVVector
../../_images/46.png
  1. پلاگین ساز از شما می خواهد که نوع فایل هایی را که باید تولید کنید. انتخاب پیش فرض را نگه دارید و روی Next کلیک کنید .
../../_images/56.png
  1. از آنجایی که قصد انتشار افزونه را نداریم، می‌توانید مقادیر ردیاب اشکال ، مخزن و صفحه اصلی را به‌طور پیش‌فرض رها کنید. کادر پرچم گذاری افزونه به عنوان آزمایشی را در پایین علامت بزنید و روی Next کلیک کنید .
../../_images/66.png
  1. از شما خواسته می شود که یک دایرکتوری برای افزونه خود انتخاب کنید. در حال حاضر، آن را در فهرستی که به راحتی می‌توانید در رایانه خود پیدا کنید ذخیره کنید و روی Generate کلیک کنید .
../../_images/76.png
  1. در مرحله بعد، دکمه تولید را فشار دهید . پس از ایجاد الگوی افزونه شما یک گفتگوی تایید را مشاهده خواهید کرد.
../../_images/86.png

توجه داشته باشید

ممکن است پیامی دریافت کنید که می گوید pyrcc5 در مسیر یافت نمی شود. می توانید این پیام را نادیده بگیرید.

  1. قبل از اینکه بتوانیم از افزونه جدید ایجاد شده استفاده کنیم، باید resources.qrcفایلی را که توسط افزونه ساز ایجاد شده است کامپایل کنیم. این فایل بخشی از سیستم منابع Qt است که به تمام فایل های باینری استفاده شده در افزونه ارجاع می دهد. برای این افزونه، فقط آیکون افزونه را خواهد داشت. کامپایل این فایل کد برنامه ای را تولید می کند که می تواند در پلتفرم مستقل افزونه که افزونه بر روی آن اجرا می شود استفاده شود. دستورالعمل مخصوص پلتفرم را برای این مرحله دنبال کنید.

ویندوز

اکنون می توانید compile.batفایل را (که در ابتدای بخش Python Bindings for Qt ایجاد شده است) در پوشه افزونه کپی کنید. پس از کپی کردن، روی فایل دوبار کلیک کنید تا اجرا شود. اگر اجرا با موفقیت انجام شد، یک فایل جدید را resources.pyدر پوشه مشاهده خواهید کرد .

../../_images/96.png

توجه داشته باشید

اگر این مرحله ناموفق بود، می‌توانید cmd.exeبا استفاده از دستور، پوشه پلاگین را راه‌اندازی و مرور کنید cd. فایل Batch را با اجرا اجرا کنید compile.batتا خطا را ببینید.

مک و لینوکس

ابتدا باید نصب کنید pb_tool. یک ترمینال را باز کنید و از طریق پیپ نصب کنید.

sudo pip3 install pb_tool

یک ترمینال را باز کنید و به فهرست پلاگین بروید و تایپ کنید . این دستوری را که به عنوان بخشی از Python Bindings برای بخش Qt نصب کرده بودیم اجرا می کند .pb_tool compilepyrcc5

pb_tool compile
  1. پلاگین ها در QGIS در یک پوشه خاص ذخیره می شوند. ما باید دایرکتوری پلاگین خود را در آن پوشه کپی کنیم تا بتوان از آن استفاده کرد. در QGIS، با رفتن به Settings ‣ User Profiles ‣ Open Active Profile Folder را پیدا کنید .
../../_images/109.png
  1. در پوشه پروفایل، پوشه پلاگین را در زیر پوشه python ‣ plugins کپی کنید .
../../_images/1112.png
  1. اکنون ما آماده ایم تا نگاهی به پلاگین کاملاً جدیدی که ایجاد کرده ایم داشته باشیم. QGIS را ببندید و دوباره راه اندازی کنید. به Plugins ‣ Manage and Install plugins بروید و افزونه را در تب Installed فعال کنید .Save Attributes
../../_images/1210.png
  1. متوجه خواهید شد که یک نماد جدید در نوار ابزار افزونه و یک ورودی منوی جدید در قسمت Vector ‣ Save Attributes ‣ Save Attributes as CSV` وجود دارد . آن را انتخاب کنید تا گفتگوی افزونه راه اندازی شود.
../../_images/138.png
  1. متوجه یک گفتگوی خالی جدید به نام Save Attributes خواهید شد . این گفتگو را ببندید.
../../_images/148.png
  1. اکنون کادر محاوره ای خود را طراحی می کنیم و برخی از عناصر رابط کاربری را به آن اضافه می کنیم. برنامه را باز کنید و به File ‣ Open File or Project بروید .Qt Creator
../../_images/158.png
  1. به دایرکتوری افزونه بروید و save_attributes_dialog_base.uiفایل را انتخاب کنید. روی Open کلیک کنید .
../../_images/16.gif

توجه داشته باشید

ویندوز AppDataپوشه را پنهان می کند بنابراین ممکن است آن را در گفتگوی انتخابگر فایل مشاهده نکنید. برای باز کردن آن می‌توانید اعلان File name راAppData از فهرست اصلی آن وارد کنید .

  1. دیالوگ خالی افزونه را خواهید دید. می‌توانید عناصر را از پانل سمت چپ در دیالوگ بکشید و رها کنید. یک نوع Combo Box از ابزارک های ورودی اضافه می کنیم . آن را به گفتگوی افزونه بکشید.
../../_images/178.png
  1. اندازه جعبه ترکیبی را تغییر دهید و اندازه آن را تنظیم کنید. اکنون یک صفحه نمایش ابزارک از نوع Label را در کادر محاوره بکشید.
../../_images/186.png
  1. روی برچسب متن کلیک کرده و وارد کنید .Select a layer
../../_images/195.png
  1. این فایل را با رفتن به File ‣ Save save_attributes_dialog_base.ui ذخیره کنید . توجه داشته باشید که نام شی جعبه ترکیبی است comboBox. برای تعامل با این شی با استفاده از کد پایتون، باید به آن با این نام اشاره کنیم.
../../_images/205.png
  1. بیایید افزونه خود را دوباره بارگذاری کنیم تا بتوانیم تغییرات را در پنجره گفتگو مشاهده کنیم. به Plugin ‣ Plugin Reloader ‣ افزونه ای را برای بارگیری مجدد انتخاب کنید . SaveAttributesدر گفتگوی Configure Plugin Reloader را انتخاب کنید .
../../_images/2110.png
  1. برای بارگیری آخرین نسخه افزونه، روی دکمه Reload پلاگین کلیک کنید . روی دکمه Save Attributes as CSV کلیک کنید تا کادر گفتگوی جدید طراحی شده باز شود.
../../_images/225.png
  1. بیایید مقداری منطق به افزونه اضافه کنیم که باکس ترکیبی را با لایه های بارگذاری شده در QGIS پر می کند. به فهرست پلاگین بروید و فایل را save_attributes.pyدر یک ویرایشگر متن بارگذاری کنید. ابتدا، در بالای فایل با وارد کردن های دیگر وارد کنید:
    from qgis.core import QgsProject
    

    سپس تا انتها به پایین اسکرول کنید و run(self)روش را پیدا کنید. این روش زمانی فراخوانی می شود که روی دکمه نوار ابزار کلیک کنید یا آیتم منوی افزونه را انتخاب کنید. کد زیر را در ابتدای روش اضافه کنید. این کد لایه های بارگذاری شده در QGIS را دریافت می کند و آن را comboBoxاز گفتگوی افزونه به شی اضافه می کند.

    # Fetch the currently loaded layers
    layers = QgsProject.instance().layerTreeRoot().children()
    # Clear the contents of the comboBox from previous runs
    self.dlg.comboBox.clear()
    # Populate the comboBox with names of all the loaded layers
    self.dlg.comboBox.addItems([layer.name() for layer in layers])
    
../../_images/23a.png../../_images/23b.png
  1. به پنجره اصلی QGIS بازگردید، با کلیک بر روی دکمه بارگذاری مجدد افزونه، افزونه را بارگیری مجدد کنید . برای آزمایش این قابلیت جدید، باید چند لایه در QGIS بارگذاری کنیم. پس از بارگیری چند لایه، افزونه را با رفتن به قسمت Vector ‣ Save Attributes ‣ Save Attributes as CSV راه اندازی کنید . خواهید دید که جعبه ترکیبی ما اکنون با نام لایه هایی که در QGIS بارگذاری شده اند پر شده است.
../../_images/245.png
  1. بیایید عناصر رابط کاربری باقی مانده را اضافه کنیم. به Qt Creator برگردید و save_attributes_dialog_base.uiفایل را بارگیری کنید. یک Label صفحه نمایش ویجت اضافه کنید و متن را به . یک نوع Input Widget اضافه کنید که مسیر فایل خروجی را که کاربر انتخاب کرده است نشان دهد. سپس یک نوع Button اضافه کنید و برچسب دکمه را به . به نام اشیاء ویجت‌هایی که باید برای تعامل با آنها استفاده کنیم، توجه کنید. فایل را ذخیره کنید.Select output fileLineEditPush Button...
../../_images/255.png
  1. اکنون کد پایتون را اضافه می کنیم تا وقتی کاربر روی ...دکمه فشار کلیک می کند، مرورگر فایل را باز کند و مسیر انتخابی را در ویجت ویرایش خط نشان دهد. save_attributes.pyفایل را در یک ویرایشگر متن باز کنید . اضافه کردن QFileDialogبه QtWidgetsلیست واردات در بالای فایل.
../../_images/264.png
  1. یک متد جدید به نام select_output_fileبا کد زیر اضافه کنید. این کد یک مرورگر فایل را باز می کند و ویجت ویرایش خط را با مسیر فایلی که کاربر انتخاب کرده است پر می کند. توجه داشته باشید، چگونه getSaveFileNameیک تاپل را با نام فایل و فیلتر استفاده شده برمی گرداند.
def select_output_file(self):
  filename, _filter = QFileDialog.getSaveFileName(
    self.dlg, "Select   output file ","", '*.csv')
  self.dlg.lineEdit.setText(filename)

../../_images/275.png

  1. حال باید کدی را اضافه کنیم تا با کلیک روی دکمه select_output_file متد فراخوانی شود. به روش پایین بروید runو خط زیر را در بلوکی که دیالوگ مقداردهی شده است اضافه کنید. این کد select_output_fileروش را به clickedسیگنال ویجت دکمه فشاری متصل می کند.
self.dlg.pushButton.clicked.connect(self.select_output_file)

../../_images/285.png

  1. به QGIS برگردید، افزونه را دوباره بارگیری کنید و آن را اجرا کنید. اگر همه چیز خوب پیش رفت، می توانید روی ...دکمه کلیک کنید و یک فایل متنی خروجی را از دیسک خود انتخاب کنید.
../../_images/294.png
  1. وقتی روی OK در گفتگوی افزونه کلیک می کنید، هیچ اتفاقی نمی افتد. دلیلش این است که ما منطقی برای بیرون کشیدن اطلاعات ویژگی از لایه و نوشتن آن در فایل متنی اضافه نکرده ایم. ما اکنون تمام قطعات را برای انجام این کار آماده کرده ایم. جایی را در runروشی که می گوید پیدا کنید pass. آن را با کد زیر جایگزین کنید. توضیح این کد را می توان در شروع با برنامه نویسی پایتون (QGIS3) یافت .
    filename = self.dlg.lineEdit.text()
    with open(filename, 'w') as output_file:
      selectedLayerIndex = self.dlg.comboBox.currentIndex()
      selectedLayer = layers[selectedLayerIndex].layer()
      fieldnames = [field.name() for field in selectedLayer.fields()]
      # write header
      line = ','.join(name for name in fieldnames) + '\n'
      output_file.write(line)
      # write feature attributes
      for f in selectedLayer.getFeatures():
        line = ','.join(str(f[name]) for name in fieldnames) + '\n'
        output_file.write(line)
    

    ../../_images/304.png

  2. ما آخرین چیزی را برای اضافه کردن داریم. وقتی عملیات با موفقیت تمام شد، باید همان را به کاربر نشان دهیم. روش ترجیحی برای دادن اعلان به کاربر در QGIS از طریق self.iface.messageBar().pushMessage()روش است. Qgisبه qgis.coreلیست واردات در بالای فایل اضافه کنید و کد زیر را در انتهای runروش اضافه کنید.
self.iface.messageBar().pushMessage(
  "Success", "Output file written at " + filename,
  level=Qgis.Success, duration=3)

../../_images/31a.png../../_images/31b.png

  1. اکنون افزونه ما آماده است. افزونه را دوباره بارگیری کنید و آن را امتحان کنید. متوجه خواهید شد که فایل متنی خروجی که انتخاب کرده اید دارای ویژگی های لایه برداری است.
../../_images/323.png
  1. می توانید دایرکتوری افزونه را فشرده کرده و با کاربران خود به اشتراک بگذارید. آنها می توانند محتویات را در فهرست پلاگین خود باز کرده و افزونه شما را امتحان کنند. اگر این یک افزونه واقعی بود، آن را در مخزن پلاگین QGIS آپلود می کردید تا همه کاربران QGIS بتوانند افزونه شما را پیدا و دانلود کنند.

توجه داشته باشید

این افزونه فقط برای نمایش است. این افزونه را منتشر نکنید و آن را در مخزن افزونه QGIS آپلود نکنید.

فایل کامل save_attributes.pyبه عنوان مرجع در زیر آمده است.

# -*- coding: utf-8 -*-
"""
/***************************************************************************
 SaveAttributes
                                 A QGIS plugin
 This plugin saves the attributes of the selected vector layer as a CSV file.
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2019-03-28
        git sha              : $Format:%H$
        copyright            : (C) 2019 by Ujaval Gandhi
        email                : ujaval@spatialthoughts.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""
from PyQt5.QtCore import QSettings, QTranslator, qVersion, QCoreApplication
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QAction, QFileDialog
from qgis.core import QgsProject, Qgis

# Initialize Qt resources from file resources.py
from .resources import *
# Import the code for the dialog
from .save_attributes_dialog import SaveAttributesDialog
import os.path


class SaveAttributes:
    """QGIS Plugin Implementation."""

    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'SaveAttributes_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Save Attributes')

        # Check if plugin was started the first time in current QGIS session
        # Must be set in initGui() to survive plugin reloads
        self.first_start = None

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('SaveAttributes', message)


    def add_action(
        self,
        icon_path,
        text,
        callback,
        enabled_flag=True,
        add_to_menu=True,
        add_to_toolbar=True,
        status_tip=None,
        whats_this=None,
        parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            # Adds plugin icon to Plugins toolbar
            self.iface.addToolBarIcon(action)

        if add_to_menu:
            self.iface.addPluginToVectorMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/save_attributes/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'Save Attributes as CSV'),
            callback=self.run,
            parent=self.iface.mainWindow())

        # will be set False in run()
        self.first_start = True


    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginVectorMenu(
                self.tr(u'&Save Attributes'),
                action)
            self.iface.removeToolBarIcon(action)

    def select_output_file(self):
      filename, _filter = QFileDialog.getSaveFileName(
        self.dlg, "Select   output file ","", '*.csv')
      self.dlg.lineEdit.setText(filename)
      
    def run(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start == True:
            self.first_start = False
            self.dlg = SaveAttributesDialog()
            self.dlg.pushButton.clicked.connect(self.select_output_file)

        
        # Fetch the currently loaded layers
        layers = QgsProject.instance().layerTreeRoot().children()
        # Clear the contents of the comboBox and lineEdit from previous runs
        self.dlg.comboBox.clear()
        self.dlg.lineEdit.clear()

        # Populate the comboBox with names of all the loaded layers
        self.dlg.comboBox.addItems([layer.name() for layer in layers])
        
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
          filename = self.dlg.lineEdit.text()
          with open(filename, 'w') as output_file:
            selectedLayerIndex = self.dlg.comboBox.currentIndex()
            selectedLayer = layers[selectedLayerIndex].layer()
            fieldnames = [field.name() for field in selectedLayer.fields()]
            # write header
            line = ','.join(name for name in fieldnames) + '\n'
            output_file.write(line)
            # write feature attributes
            for f in selectedLayer.getFeatures():
              line = ','.join(str(f[name]) for name in fieldnames) + '\n'
              output_file.write(line)
          self.iface.messageBar().pushMessage(
            "Success", "Output file written at " + filename,
            level=Qgis.Success, duration=3)

اگر می خواهید بازخورد بدهید یا تجربه خود را در مورد این آموزش به اشتراک بگذارید، لطفاً در زیر نظر دهید. (به حساب GitHub نیاز دارد)


دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

خانهدربارهتماسارتباط با ما