Гузариш ба мундариҷа
Мавзӯи 2 аз 6

Равзанаҳо, виджетҳо ва layout-ҳо

Равзанаҳо ва виджетҳо барои чӣ лозиманд

Дар барномаи консолӣ корбар ба саволҳо бо навбат ҷавоб медиҳад. Дар барномаи равзанадор ӯ қадами навбатиро худаш интихоб мекунад: матн менависад, тугмаро пахш мекунад ё андозаи равзанаро тағйир медиҳад. Муҳаррирҳо, ҳисобгарҳо ва барномаҳои баҳисобгирӣ ҳамин тавр кор мекунанд. Ба мо унсурҳои интерфейс ва роҳи посух додан ба амалҳои корбар лозиманд.

PySide6 Python-ро бо Qt мепайвандад. Дар курс бастаи PySide6-Essentials истифода мешавад: он модулҳои зарурии QtCore, QtGui ва QtWidgets-ро дорад. Бастаи пурраи PySide6 модулҳои дигарро низ илова мекунад, вале барои ин дарсҳо онҳо лозим нестанд. Мо тадриҷан барномаи қайдҳоро месозем; аввал сохтани равзанаи онро меомӯзем.

1. Барнома ва равзана объектҳои гуногунанд

QApplication танзимоти умумӣ ва коркарди рӯйдодҳои барномаро идора мекунад. Барои ҳар раванд як чунин объект лозим аст ва он пеш аз виджетҳо сохта мешавад. Виджет унсури интерфейс аст. QWidget бе волид метавонад равзанаи мустақил бошад; ҳамин синф бо волид метавонад қисми равзанаи дигар бошад.

Дар мисолҳо ифодаи QApplication.instance() or QApplication([]) объекти мавҷудаи барномаро мегирад ё онро месозад. Рӯйхати холӣ маънои онро дорад, ки аргументҳои сатри фармон ба барнома дода намешаванд. Дар барномаи алоҳида метавонед sys.argv диҳед.

from PySide6.QtWidgets import QApplication, QWidget

app = QApplication.instance() or QApplication([])
window = QWidget()
window.setWindowTitle("Панел")
print(QApplication.instance() is app, window.windowTitle())

Натиҷа:

True Панел

setWindowTitle сарлавҳаро иваз мекунад ва windowTitle() онро мехонад. Сохтани равзана ҳанӯз онро дар экран нишон намедиҳад. Барои ин show() лозим аст.

2. Намоиши равзана ва даври рӯйдодҳо

Даври рӯйдодҳо (event loop) паёмҳои системаро интизор шуда, ба объектҳои мувофиқ мерасонад: масалан, тугмаро аз пахши муш огоҳ мекунад. app.exec() ин даврро оғоз карда, одатан баъди баста шудани равзанаи охирин идоракуниро бармегардонад. Бе он барномаи одӣ ба охир расида, қатъ мешавад.

Мисоли навбатӣ пурра аст, вале равзанаро худкор мебандад: QTimer.singleShot як даъвати якдафъаинаро ба нақша мегирад. Фосилаи 0 имкон медиҳад он баъди оғози коркарди рӯйдодҳо иҷро шавад. Барои дастӣ бастани равзана сатри таймерро бардоред.

from PySide6.QtCore import QTimer
from PySide6.QtWidgets import QApplication, QWidget

app = QApplication.instance() or QApplication([])
window = QWidget()
window.setWindowTitle("Панел")
window.resize(320, 160)
window.show()
QTimer.singleShot(0, window.close)
print(app.exec())

Натиҷа:

0

Сифр рамзи анҷоми давр аст, на муҳтавои равзана. Дар файли барнома сохтани app, равзана ва даъвати exec()-ро одатан зери if __name__ == "__main__": мегузоранд, то ворид кардани файл бо import равзанаро накушояд.

3. Матн ва ҳолати виджет

QLabel матнро нишон медиҳад ва QLineEdit таҳрири як сатрро имкон медиҳад. Placeholder ишора дар майдони холӣ аст: он қимати text() намешавад. Методҳои монанди setText(...) қиматро менависанд ва text() сатри ҷориро бармегардонад. Виджет фосилаҳоро худкор намебардорад; барои ин коркарди ҷудогонаи Python лозим аст.

from PySide6.QtWidgets import QApplication, QLabel, QLineEdit

app = QApplication.instance() or QApplication([])
edit = QLineEdit()
edit.setPlaceholderText("Номи муаллиф")
print(repr(edit.text()))
edit.setText("  Лайло  ")
label = QLabel(edit.text().strip())
print(label.text())

Натиҷа:

''
Лайло

Баъди гузоштани ишора майдон ҳанӯз холӣ аст, бинобар ин аввал '' чоп мешавад. Дар мисол strip() пеш аз сохтани навишта фосилаҳои канориро мебардорад. Навишта ба майдон худкор пайваст нест: тағйироти баъдии майдонро алоҳида коркард кардан лозим аст.

Барои чанд сатр QTextEdit ва QPlainTextEdit мувофиқанд: матни одии онҳоро бо toPlainText() мехонанд. QCheckBox ҳолати аломати интихобро (isChecked()) ва QSpinBox ададро (value()) нигоҳ медорад. Инҳо навъҳои гуногуни додаанд, бинобар ин аз ҳар унсури интерфейс text()-ро интизор нашавед.

4. Layout ба ҷойи координатаҳои доимӣ

Layout ҷойро байни унсурҳо тақсим карда, ҳангоми тағйири равзана мавқеи онҳоро аз нав ҳисоб мекунад. QVBoxLayout сутун ва QHBoxLayout қатор месозад. Як layout метавонад дар дохили дигараш бошад: берунӣ тамоми қатор ва дохилӣ унсурҳои онро идора мекунад.

from PySide6.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QVBoxLayout, QHBoxLayout

app = QApplication.instance() or QApplication([])
window = QWidget()
column = QVBoxLayout(window)
row = QHBoxLayout()
field = QLineEdit()
row.addWidget(QLabel("Муаллиф"))
row.addWidget(field)
column.addLayout(row)
print(column.count(), row.count(), field.parent() is window)

Натиҷа:

1 2 True

Дар сутун як унсур — қатори дохилӣ — ва дар қатор ду виджет ҳаст. Баъди насби layout-ҳо равзана волиди майдон мешавад. addWidget виджет ва addLayout layout қабул мекунад. Як равзана бояд як layout-и асосӣ дошта бошад; layout-ҳои иловагиро ба он мегузоранд.

Шабакаи QGridLayout виджетҳоро дар сатрҳо ва сутунҳо бо индексҳои аз сифр ҷойгир мекунад. Ду адади иловагии addWidget шумораи сатрҳо ва сутунҳои ишғолшударо медиҳанд, на координатаҳои охирро.

from PySide6.QtWidgets import QApplication, QWidget, QLabel, QGridLayout

app = QApplication.instance() or QApplication([])
window = QWidget()
grid = QGridLayout(window)
grid.addWidget(QLabel("A"), 0, 0)
grid.addWidget(QLabel("B"), 1, 0, 1, 2)
print(grid.getItemPosition(1))

Натиҷа:

(1, 0, 1, 2)

getItemPosition(1) мавқеи унсури дуюми иловашударо бармегардонад: сатр, сутун, баландӣ ва паҳно бо ҳуҷайраҳо. Дар ин ҷо B аз сатри 1 ва сутуни 0 оғоз шуда, ду сутунро мегирад. Ҳамин тавр майдонҳо ва тугмаҳои васеъро бе таъйини андоза бо пиксел месозанд.

5. Пайвастани амал ва посух

Сигнал аз рӯй додани рӯйдод хабар медиҳад. Слот функсияест, ки дар посух даъват мешавад. Пахши QPushButton сигнали clicked медиҳад. connect худи функсияро мегирад: on_click, бе қавс.

from PySide6.QtWidgets import QApplication, QLabel, QPushButton

app = QApplication.instance() or QApplication([])
label = QLabel("Интизорӣ")
button = QPushButton("Санҷидан")

def on_click():
    label.setText("Омода")

button.clicked.connect(on_click)
print(label.text())
button.click()
print(label.text())
button.setEnabled(False)
label.setText("Таваққуф")
button.click()
print(label.text())

Натиҷа:

Интизорӣ
Омода
Таваққуф

Дар ин ҷо слот навиштаро иваз мекунад ва click() пахшро тақлид мекунад. Тугмаи ғайрифаъол (setEnabled(False)) ба click() посух намедиҳад, бинобар ин қимати охирин бетағйир мемонад. Ин ҳам барои интерфейси воқеӣ ва ҳам барои санҷиши худкор муҳим аст.

Дар дохил чӣ рӯй медиҳад

Равзана соҳиби виджетҳои фарзанд аст ва layout геометрияи онҳоро идора мекунад. Вақте равзана баъди баста шудан нобуд мешавад, Qt объектҳои фарзанди онро озод мекунад. Истинодҳои монанди self.label имкон медиҳанд методҳои синфатон баъдтар ба виджет дастрасӣ дошта бошанд; тағйирёбандаи маҳаллии методи дигар барои ин мувофиқ нест.

Занҷираи посух чунин аст: рӯйдоди система → сигнали тугма → функсияи пайвастшуда → тағйири ҳолати навишта → бозрасмкашӣ. Layout муайян мекунад, ки унсур дар куҷо бошад ва слот муайян мекунад, ки чӣ тағйир ёбад. Виджетҳо қоидаҳои барномаи шуморо худ намефаҳманд.

Дар масъалаҳо равзана бе экран сохта мешавад ва санҷиш setText() ва click()-ро даъват мекунад. Аз ҳамин сабаб мисолҳо ҳолати объектҳоро чоп мекунанд: онро бе равзанаи кушода низ санҷидан мумкин аст. Барои кори одӣ дар компютер show() ва даври рӯйдодҳо лозиманд.

Хатоҳои маъмул ва ислоҳи онҳо

  1. QWidget() пеш аз QApplication(...): Qt барномаро бо паёми зарурати барнома қатъ мекунад. Аввал app, баъд ҳамаи виджетҳоро созед.
  2. button.clicked.connect(on_click()): функсия фавран иҷро шуда, натиҷаи он, аксаран None, ба connect меравад. on_click-ро бе қавс диҳед.
  3. column.addWidget(row), вақте row layout аст: хатои навъ пайдо мешавад. column.addLayout(row) истифода баред.
  4. Ду бор даъват кардани clicked.connect(on_click): як пахш коркардкунандаро ду бор даъват мекунад. Онро ҳангоми танзими равзана як бор пайваст кунед.
  5. Фаромӯш кардани show() ё app.exec(): равзана пайдо намешавад ё барнома фавран анҷом меёбад. Ҳар ду қадамро дар нуқтаи оғози барнома санҷед.

Ёддошти кӯтоҳ

Вазифа Восита
Сохтани барнома як QApplication пеш аз виджетҳо
Намоиши равзана ва коркарди рӯйдодҳо show(), баъд app.exec()
Навишта / вуруди яксатра QLabel / QLineEdit
Хондан / иваз кардани матн text() / setText(...)
Сутун / қатор / шабака QVBoxLayout / QHBoxLayout / QGridLayout
Гузоштани виджет / layout addWidget / addLayout
Посух ба пахш clicked.connect(function)
Фаъол ё ғайрифаъол кардани амал setEnabled(True/False)