უახლესი სტატიები
მთავარი / ოფისი / Qt შემქმნელის ბიბლიოთეკის აღწერა. Qt Creator-ის ინსტალაცია და კონფიგურაცია. აპლიკაციის ფანჯარაში ვიჯეტების განთავსების მარტივი მაგალითი

Qt შემქმნელის ბიბლიოთეკის აღწერა. Qt Creator-ის ინსტალაცია და კონფიგურაცია. აპლიკაციის ფანჯარაში ვიჯეტების განთავსების მარტივი მაგალითი

ეს არის მრავალპლატფორმული პროგრამული უზრუნველყოფის განვითარების ინსტრუმენტარიუმი C++ პროგრამირების ენაზე. ასევე არსებობს მრავალი სხვა პროგრამირების ენა: Python - PyQt, Ruby - QtRuby, Java - Qt Jambi, PHP - PHP-Qt და სხვა.
საშუალებას გაძლევთ გაუშვათ მისი დახმარებით დაწერილი პროგრამული უზრუნველყოფა ყველაზე თანამედროვეში ოპერატიული სისტემათითოეული OS-ისთვის პროგრამის უბრალოდ შედგენით, წყაროს კოდის შეცვლის გარეშე. მოიცავს ყველა ძირითად კლასს, რომელიც შეიძლება საჭირო გახდეს აპლიკაციის პროგრამული უზრუნველყოფის შემუშავებისას, დაწყებული გრაფიკული ინტერფეისის ელემენტებიდან ქსელთან მუშაობის კლასებამდე, მონაცემთა ბაზებთან და XML-თან. Qt არის სრულად ობიექტზე ორიენტირებული, ადვილად გაფართოებადი და მხარს უჭერს კომპონენტებზე დაფუძნებულ პროგრამირების ტექნიკას.
ამ სტატიაში მე გაჩვენებთ, თუ როგორ უნდა დაწეროთ მარტივი პროგრამა "Hello, World!". Qt4 ბიბლიოთეკის გამოყენებით

განვითარების გარემო

ჯერ განვსაზღვროთ განვითარების გარემო. პირადად მე ვიყენებ cross-platform IDE Code::Blocks პროგრამის დასაწერად (შეგიძლიათ წაიკითხოთ მეტი Qt4-ით ამ IDE-ში მუშაობის შესახებ). ასევე არის Eclipse-ში Qt-თან მუშაობის დანამატები. Qt-ის კომერციული ვერსია MS Windows-ისთვის შეიძლება ინტეგრირებული იყოს MSVS-ში. პროგრამები ასევე შეიძლება დაიწეროს ნებისმიერში ტექსტის რედაქტორიდა შემდეგ შეადგინეთ ისინი ბრძანების ხაზიდან.
სიცხადისთვის, მე გაჩვენებთ, თუ როგორ უნდა შევადგინოთ Qt-ში დაწერილი პროგრამები ხელით.

პირველი პროგრამა

პირველი, შექმენით ფაილი ნებისმიერ ტექსტურ რედაქტორში და დაარქვით სახელი, მაგალითად main.cpp
მოდით ჩავწეროთ მასში შემდეგი:
  1. #შეიცავს
  2. #შეიცავს
  3. QApplication აპლიკაცია (argc, argv);
  4. QDialog *dialog = new QDialog;
  5. QLabel *label = new QLabel(dialog);
  6. label->setText( "Გამარჯობა მსოფლიო!" );
  7. დიალოგი->ჩვენება();
  8. დააბრუნეთ app.exec();

1 და 2 სტრიქონებში ჩვენ ჩავრთეთ Qt სათაურის ფაილები, რომლებშიც განლაგებულია ძირითადი კლასები.
მე-4 ხაზზე ჩვენ გამოვაცხადეთ მთავარი ფუნქცია - მთავარი ფუნქცია, საიდანაც იწყება ნებისმიერი პროგრამის შესრულება. ის აბრუნებს მთელ რიცხვს (პროგრამის შედეგს; 0 - თუ ყველაფერი რიგზეა) და იღებს ორ ცვლადს შეყვანად - ბრძანების ხაზის პარამეტრების რაოდენობას და მასივს, რომელშიც ისინი ინახება.
მე-5 ხაზზე ვქმნით აპლიკაციის ობიექტს. ჩვენ გადავცემთ ბრძანების ხაზის ცვლადებს ამ ობიექტს.
მე-6 სტრიქონზე ვქმნით დიალოგს - მართკუთხა ფორმის გრაფიკულ ფანჯარას სათაურის ზოლით და ღილაკებით ზედა მარჯვენა კუთხეში. შექმენით ლეიბლი (სტრიქონი 7). როდესაც ჩვენ ვქმნით ლეიბლს, ჩვენ გადავცემთ მაჩვენებელს დიალოგში მის კონსტრუქტორს, რომელიც ხდება მისი მშობელი. როდესაც თქვენ წაშლით მშობელს, მისი ყველა შვილი ავტომატურად იშლება, რაც ძალიან მოსახერხებელია. შემდეგ ჩვენ ვაყენებთ ლეიბლის ტექსტს setText() ფუნქციის გამოძახებით (სტრიქონი 8). როგორც მაგალითიდან ხედავთ, ნაჩვენები ტექსტისთვის შეგიძლიათ გამოიყენოთ html ტეგები.
მე-9 სტრიქონზე ჩვენ ვაჩვენებთ ჩვენს ლეიბლის დიალოგს ეკრანზე.
ბოლოს მე-10 სტრიქონზე ვიწყებთ აპლიკაციის ოპერაციული სისტემის მოვლენის ციკლს. ჩვენ ვაბრუნებთ ობიექტის მუშაობის შედეგს პროგრამის შედეგად.

კომპილაცია

ახლა შევადგინოთ დაწერილი პროგრამა.
მოდით გადავიდეთ დირექტორიაში, სადაც შევინახეთ ჩვენი main.cpp ფაილი და გაუშვით ბრძანება

$ qmake -პროექტი

ეს შექმნის Qt4 პროექტის შაბლონს, რომელიც ავტომატურად მოიცავს ამ დირექტორიაში მდებარე ყველა კოდის ფაილს. შედეგი იქნება ფაილი იგივე სახელით, როგორც მიმდინარე დირექტორია და გაფართოება .pro. ეს ასე გამოიყურება:

TEMPLATE=აპი
სამიზნე =
DEPENDPATH += .
INCLUDEPATH += .

#შეყვანა
SOURCES += main.cpp

შედეგად, ჩვენ მივიღებთ Makefile-ს, რომელსაც ვიყენებთ პროგრამის კომპილაციისთვის შემდეგი ბრძანების გაშვებით:

დაველოდოთ კომპილაციის პროცესის დასრულებას და გავუშვათ ჩვენი პირველი პროგრამა. ეს დაახლოებით ასე გამოიყურება:

მეორე პროგრამა

შექმნილ ფანჯრებსა და სხვა ვიჯეტებზე სრული კონტროლის მოსაპოვებლად, თქვენ უნდა შექმნათ მათგან მიღებული კლასები. მოდით შევქმნათ მიღებული კლასი MyDialog. ჩვენ გამოვიყენებთ QDialog კლასს, როგორც მშობელ კლასს. ჩვენ განვათავსებთ ჩვენი კლასის აღწერას სათაურის ფაილში mydialog.h:
  1. #შეიცავს
  2. #შეიცავს
  3. #შეიცავს
  4. #შეიცავს
  5. კლასი MyDialog: საჯარო QDialog (
  6. Q_OBJECT
  7. საჯარო:
  8. MyDialog(QWidget *მშობელი = 0);
* ეს საწყისი კოდი მონიშნული იყო Source Code Highlighter-ით.
პირველ ოთხ სტრიქონში ჩვენ შევაქვთ გამოყენებული გრაფიკული ელემენტების საჭირო სათაურის ფაილები - დიალოგი, ღილაკი, ლეიბლი და ვერტიკალური განლაგების მენეჯერი. გამოიყენეთ ისეთი დიდი სათაურის ფაილები, როგორიცაა , მსხვილ პროექტებში არ არის რეკომენდებული, რადგან ეს ზრდის შედგენის დროს.
მეექვსე ხაზზე, ჩვენ განვსაზღვრეთ ჩვენი კლასი QDialog-დან გამომდინარე.
შემდეგ სტრიქონზე ჩვენ დავაზუსტეთ Q_OBJECT მაკრო, რომელიც ეუბნება Qt წინასწარ პროცესორს, რომ ეს კლასი გამოიყენებს დამატებით Qt ფუნქციებს, მაგალითად, სიგნალისა და სლოტის სისტემას.
მე-9 სტრიქონზე ჩვენ ვაზუსტებთ ჩვენი დიალოგური ფანჯრის კონსტრუქტორს. მას აქვს მხოლოდ ერთი შეყვანის პარამეტრი - მაჩვენებელი მშობელი ობიექტისკენ (0 თუ არ არის მშობელი).
ჩვენ განვსაზღვრავთ ჩვენი კლასის კონსტრუქტორს mydialog.cpp ფაილში:
  1. #include "mydialog.h"
  2. MyDialog::MyDialog(QWidget *მშობელი) : QDialog(მშობელი) (
  3. QVBoxLayout *განლაგება = ახალი QVBoxLayout(ეს);
  4. QLabel *label = new QLabel(this);
  5. label->setText( "Გამარჯობა მსოფლიო!" );
  6. QPushButton *button = new QPushButton(this );
  7. button->setText("დახურვა");
  8. განლაგება->addWidget(label);
  9. განლაგება->addWidget(ღილაკი);
  10. connect(ღილაკი, SIGNAL(დააწკაპუნეთ()), ეს , SLOT(close()));
* ეს საწყისი კოდი მონიშნული იყო Source Code Highlighter-ით.

მე-4 ხაზზე ჩვენ ვქმნით განლაგების მენეჯერს, რომელიც ავტომატურად აჩვენებს მასში დამატებულ ყველა ვიჯეტს ვერტიკალურად. წარწერის შექმნა წინა მაგალითის მსგავსია.
მე-7 და მე-8 სტრიქონებში ვქმნით ღილაკს და ვაყენებთ მის ტექსტს. მომდევნო ორ სტრიქონზე ვამატებთ ჩვენს ვიჯეტებს განლაგების მენეჯერს ისე, რომ ის ავტომატურად მოაწყობს მათ.
მე-11 სტრიქონზე ჩვენ ვაკავშირებთ ღილაკის დაწკაპუნებულ() სიგნალს ჩვენი დიალოგური ფანჯრის დახურვის() სლოტთან. თითოეულ Qt ობიექტს შეიძლება ჰქონდეს საკუთარი სიგნალები და სლოტები, რომლებიც შეიძლება დაკავშირებული იყოს სხვა ობიექტების სიგნალებთან და სლოტებთან და ამით დაუკავშირდეს პროგრამის ელემენტებს.
main.cpp ფაილი ასე გამოიყურება:
  1. #შეიცავს
  2. #include "mydialog.h"
  3. int main(int argc, char * argv) (
  4. QApplication აპლიკაცია (argc, argv);
  5. MyDialog *dialog = ახალი MyDialog;
  6. დიალოგი->ჩვენება();
  7. დააბრუნეთ app.exec();
* ეს საწყისი კოდი მონიშნული იყო Source Code Highlighter-ით.

პროექტის გუნდურად აღდგენა

$ qmake -პროექტი

ისე, რომ მას ავტომატურად დაემატება ახალი ფაილები და ვაკომპლექტებთ. ასე გამოიყურება ჩვენი ახალი პროგრამა:

მესამე პროგრამა

თუ დიალოგური ფანჯარა შეიცავს უამრავ გრაფიკულ ელემენტს, მაშინ ასეთი ფანჯრების შექმნა შეიძლება საკმაოდ დამღლელი იყოს. ამ პროცესის გასამარტივებლად, არსებობს ინსტრუმენტი სახელწოდებით Qt Designer. მოდით გავუშვათ იგი

და აირჩიეთ დიალოგური ფანჯრის შექმნა ღილაკების გარეშე. ჩვენ ვამატებთ მას ლეიბლს და ღილაკს და ვასწორებთ მათ ტექსტს. Signal/Slot Editor ხელსაწყოს გამოყენებით ჩვენ ვაკავშირებთ ღილაკის დაწკაპუნებულ() სიგნალს დიალოგური ფანჯრის დახურვის() სლოტთან. ჩვენ ვაწყობთ მათ ვერტიკალურად განლაგების მენეჯერის გამოყენებით. შეინახეთ მიღებული ფაილი სახელით mydialog.ui. მოგვიანებით ის ავტომატურად გადაიქცევა სათაურის ფაილად სახელად ui_mydialog.h.
ჩვენ ვცვლით ჩვენი დიალოგური ფანჯრის mydialog.h სათაურის ფაილს შემდეგნაირად:

დამწყები პროგრამისტი მუდმივად ეჭვობს, რომელი ტექნოლოგიების დაუფლება უნდა დაიწყოს, ამა თუ სხვა. უნდა ისწავლოს თუ არა დამწყებმა პროგრამისტმა Qt? აუცილებლად აუცილებელია! მაგალითად, წაიკითხეთ ეს პოსტი ან მოძებნეთ რამე ინტერნეტში. ჯერ კიდევ არ ხართ დარწმუნებული, გჭირდებათ თუ არა Qt? თუ თქვენ წერთ C++, თქვენ უნდა იცოდეთ Qt, უბრალოდ არ გაქვთ სხვა ალტერნატივა.

მაშ, წავიდეთ...

მოდით, მაგალითად, დავწეროთ მარტივი კალკულატორი - დავამატოთ ორი რიცხვი.

ჩვენ ვქმნით ახალი პროექტი. როგორც ვხედავთ, არსებობს რამდენიმე სახის აპლიკაცია. ჩვენ, როგორც დამწყებთათვის, ვირჩევთ "Qt ვიჯეტების აპლიკაცია":

ჩვენ მივუთითებთ პროექტის სახელს და საქაღალდეს ფაილების განსათავსებლად, ჩემთვის: C:\projects\qt

Qt ავტომატურად წარმოქმნის შემდეგ ფაილებს:

  • lesson1.pro - პროექტის ფაილი
  • main.cpp - მთავარი ფაილი main() ფუნქციით
  • mainwindow.cpp - მთავარი ფანჯრის წყაროს კოდი
  • mainwindow.h - მთავარი ფანჯრის სათაურის ფაილი
  • mainwindow.ui - მთავარი ფანჯრის ფორმის ფაილი

დააჭირეთ ღილაკს "დასრულება" - იხსნება Qt-ში პროგრამების შემუშავების რედაქტორი.

ახლა ყველაფერი გასაგები უნდა იყოს ახალბედა Qt დეველოპერისთვის...

გახსენით მთავარი ფორმა (ამისთვის გადადით mainwindow.ui-ზე).

მარცხნივ არის კომპონენტები ეკრანის ფორმის შესაქმნელად, მარჯვნივ არის თავად ფორმა, ის ცარიელია. მოდით დავამატოთ საჭირო კომპონენტები და არ დაგავიწყდეთ დაასახელოთ QLineEdit შეყვანის ველები ასე: edtA, edtB და edtC, შესაბამისად.

ჩვენ ვხედავთ შეყვანის ველებს ეკრანზე, მათ წარწერებს მარცხნივ და ღილაკს "A + B =". ამ ღილაკზე დაჭერისას უნდა დავამატოთ A და B და ჩავდოთ შედეგი C-ში.

Რა უნდა გავაკეთო? ნებისმიერი ახალბედა Qt დეველოპერი ჩათვლის, რომ თქვენ უნდა მიამაგროთ ღილაკზე დაწკაპუნების დამჭერი ღილაკზე და ის მართალი იქნება! ნებისმიერ სხვა ჩარჩოებში არის ისეთი რამ, როგორიცაა ღონისძიება. მაგრამ Qt-მა გადაწყვიტა გამოეჩინა და მოიფიქრა სიგნალები/სლოტები. თუმცა, არსებითად, ეს პრაქტიკულად იგივეა.

დააწკაპუნეთ მარჯვენა ღილაკით "A + B =" ღილაკზე, იხსნება ამომხტარი მენიუ:

დააჭირეთ "სლოტზე გადასვლას"

აირჩიეთ დაწკაპუნებული() სიგნალი და კოდის რედაქტორში, რომელიც იხსნება, ჩაწერეთ პატარა კოდი Qt-ში:

Void MainWindow::on_btnOK_clicked() ( int a = ui->edtA->text().toInt(); // აიღეთ ტექსტი edtA და გადააქციეთ ის რიცხვად a int b = ui->edtB->text() .toInt ( // აიღეთ ტექსტი edtB და გადააკეთეთ რიცხვი b int c = a + b // დაამატე რიცხვები QString s = QString: ->edtC->setText (s) // შედეგის ამობეჭდვა edtC-ში )

clicked() სიგნალის დამუშავების ფუნქციას ეწოდება on_btnOK_clicked() სლოტი.

მარტივი მაგალითი ხელით შეკრებისთვის

Qt-ის უკეთ გასაგებად, სწორი იქნებოდა კონსოლში მაინც მარტივი მაგალითის ხელით აშენება. შეკრების ტექნიკა იგივეა ნებისმიერი ზომის პროექტებისთვის და მნიშვნელოვანია იმის გაგება, თუ როგორ კეთდება ეს.

მოდით შევხედოთ GUI აპლიკაციის მარტივ მაგალითს, რომელიც ხსნის ცარიელ ფანჯარას ეკრანზე. აირჩიეთ დირექტორია დისკზე, სადაც ჩვენ შევქმნით ფაილს მთავარი.cppშემდეგი შინაარსით. მაგალითს დაემატა ხაზების ნუმერაცია მაგალითზე შემდგომი კომენტარების გასამარტივებლად. უნდა გვესმოდეს, რომ სტრიქონის ნუმერაცია არ უნდა იყოს ჩართული სამუშაო ფაილში, რადგან ის არ არის სწორი C++ გამოხატვის სინტაქსის ნაწილი.

01. #შეიცავს 02. #შეიცავს 03. 04. int main(int argc, char *argv) 05. ( 06. QApplication app(argc, argv); 07. QWidget wgt; 08. wgt.setWindowTitle(tr("Hello world")); 09. 10 .wgt.show();

01 და 02 სტრიქონები მოიცავს სათაურის ფაილებს QApplicationდა QWidget, რომელიც, სხვა საკითხებთან ერთად, შეიცავს კლასის დეკლარაციებს QApplicationდა QWidget. ჩვენს მაგალითში ჩვენ ვქმნით ამ კლასების მაგალითებს.

აღსანიშნავია Qt-ში გამოყენებული სათაურის ფაილების დასახელების მოსახერხებელი ტრადიცია. Qt-ის მე-4 ვერსიიდან, თუ დაგჭირდათ დასახელებული კლასი Qxxx, მაშინ, სავარაუდოდ, მისი განმარტება არის სათაურის ფაილში Qxxx.

ამ მაგალითში კლასი QApplicationგვაინტერესებს, როგორც შეტყობინებების შეგროვების ციკლის ორგანიზატორი, რომელიც მოვა ჩვენი GUI აპლიკაციის ფანჯარაში. იხილეთ ხაზი 11 (ფანჯრის შეტყობინების მარყუჟის დაწყება). Კლასი QApplicationგანხორციელებული სინგლტონის მსგავსებით. მათთვის, ვინც არ იცნობს ამ ტერმინს დიზაინის ნიმუშების თეორიიდან (ან შაბლონები, ინგლისურიდან. ნიმუშები) ცოტა ახსნა მოგცეთ. სინგლიტონის არსი არის ის, რომ კლასის განხორციელება ხელს უშლის მოცემული კლასის ერთზე მეტი ინსტანციის შექმნის შესაძლებლობას. ეს ფუნქცია ჩვენთვის მნიშვნელოვანია, რადგან ის გულისხმობს Qt ბიბლიოთეკის შიგნით გლობალური ცვლადის განსაზღვრის შესაძლებლობას მოცემული კლასის ერთი ეგზემპლარის მითითებით. იხილეთ აღწერილობა სიმბოლოსთვის qApp Qt დახმარებაში.

Qt ბიბლიოთეკა იყენებს ვიჯეტის ტერმინოლოგიას. ვიჯეტი- კონტრაქცია, მოწყობილობა) როგორც GUI ინტერფეისის ელემენტი. ასეთი ელემენტების თვისებების მინიმალური საერთო ნაკრები წარმოდგენილია კლასით QWidget.

06 და 07 ხაზები ქმნის აპლიკაციისა და ვიჯეტის კლასის ობიექტებს. ორივე შემთხვევაში ობიექტები იქმნება სტატიკურად. ასეთი ობიექტების სიცოცხლის ხანგრძლივობა შემოიფარგლება განცხადების ბლოკით (...), რომელშიც ისინი შეიქმნა. როგორც კი პროგრამის კოდის შესრულება მიაღწევს დახურვის ფრჩხილს, ორივე ეს ობიექტი ავტომატურად ნადგურდება. ამრიგად, ამ მაგალითში ჩვენ არ ვიფიქრებთ იმაზე, თუ როგორ გავანადგუროთ Qt ობიექტები და მოგვიანებით განვიხილავთ ამ საკითხს.

ობიექტის შექმნისას QApplicationგამოიყენება პარამეტრიზებული კონსტრუქტორი, რომელსაც გადაეცემა აპლიკაციის გაშვების არგუმენტები (კოპირებულია არგუმენტებიდან ძირითადი ფუნქციები()). კლასის ობიექტის შიგნით ეს არგუმენტები გაანალიზებულია. აპლიკაციის კლასი მხარს უჭერს გაშვების რამდენიმე პარამეტრს, რომლებიც შეგიძლიათ იხილოთ შესაბამისი კონსტრუქტორის დახმარებაში QApplication. გაშვების პარამეტრები, რომლებიც არ შედის ამ სიაში, დამოუკიდებლად უნდა გაანალიზდეს. ამ გაკვეთილის ბოლოს, აპლიკაციის მთავარ ფანჯარაში რამდენიმე კონტროლის განთავსებით, ჩვენ შემოგთავაზებთ ექსპერიმენტებს -style გაშვების პარამეტრზე, რისთვისაც ნებისმიერ Qt კონსტრუქციაში შესაძლებელია შემდეგი მნიშვნელობები: მოტივი, ფანჯრები, პლატინის.

ხაზი 08 ცვლის ვიჯეტის ობიექტის ერთ-ერთ ატრიბუტს. setWindowTitle() მეთოდის გამოყენებით, ჩვენ დავაყენეთ საკუთარი ტექსტი ჩვენი მომავალი ფანჯრის სათაურისთვის. გაითვალისწინეთ, რომ სტრიქონის სურათი შეფუთულია თარგმნის ფუნქციის გამოძახებით tr(). ეს არის განაცხადის ინტერნაციონალიზაციის მოთხოვნა. ყველა ასეთი შეფუთვისთვის, სპეციალური Qt ხელსაწყოები შეიძლება გამოყენებულ იქნას სპეციალური ფაილების შესაქმნელად სხვადასხვა ენაზე თარგმნით, რომლებიც შეიძლება გამოყენებულ იქნას აპლიკაციაში ავტომატური ჩანაცვლების შესასრულებლად. როგორც წესი, ასეთი ფაილები შედის აპლიკაციის მშენებლობაში, როგორც რესურსები.

ხაზი 10 ხსნის განაცხადის ფანჯარას. Qt4-მდე, ფანჯრის გახსნამდე, ვიჯეტი აშკარად იყო გამოცხადებული აპლიკაციის მთავარ ვიჯეტად. ეს გაკეთდა შემდეგი კოდის გამოყენებით.

App.setMainWidget(&wgt);

Qt4-დან დაწყებული, ასეთი კომუნიკაცია ხდება ავტომატურად გლობალურ მაჩვენებელზე წვდომით qAppგანაცხადის კლასის მაგალითზე.

ხაზი 11 იწყებს ოპერაციული სისტემის შეტყობინებების დამუშავების ციკლს, რომელიც მიმართულია განაცხადის ფანჯარაში. მარყუჟი მთავრდება, როდესაც აპლიკაციის დახურვის რომელიმე ბრძანება შესრულდება. განაცხადის გასასვლელი კოდი ბრუნდება exec()-ით, როდესაც მეთოდი გადის. სწორედ ეს კოდი ხდება main() ფუნქციის დაბრუნების კოდი ოპერატორის გავლით დაბრუნების.

ახლა ვცადოთ აპლიკაციის შექმნა. ამის გაკეთების ყველაზე მარტივი გზა Linux-ზეა. ამისათვის თქვენ უბრალოდ უნდა გახსნათ კონსოლი და გაუშვათ რამდენიმე ბრძანება, რომელსაც ახლა აღვწერთ. Windows-ისთვის, ასეთმა სამუშაომ შეიძლება მოითხოვოს ბილიკების დაყენება დირექტორიაში, სადაც მდებარეობს qmake პროგრამა Qt SDK-დან. ეს პროგრამა ახორციელებს QMake პროექტის აშენების სისტემის წესებს.

ჯერ უნდა გავარკვიოთ, რა არის ჩვენთვის ხელმისაწვდომი კონსოლიდან. თუ ჩვენ ვართ bash (*nix) კონსოლში, მაშინ ეს საკმაოდ მარტივია. ჩაწერეთ ბრძანება qmakeდა ორჯერ დააჭირეთ tab. ჩვენ უნდა ვნახოთ ყველა ბრძანების სია, რომელიც იწყება კომბინაციით qmake. მაგალითად, ჩემს შემთხვევაში მე ვხედავ ორ ბრძანებას: qmakeდა qmake-qt4. ეს ნიშნავს, რომ მე მაქვს ბიბლიოთეკის ორი ვერსია დაინსტალირებული საცავიდან. გუნდი qmakeშეესაბამება Qt5 ვერსიას (ნაგულისხმევი უახლესი ვერსია), და გუნდი qmake-qt4შესაბამისად შეესაბამება Qt4. ახლა, იმისდა მიხედვით, თუ რომელ ბრძანებას ვიყენებ, ან ავაშენებ Qt5 ვერსიით ან Qt4 ვერსიით.

თუ ჩვენს სისტემაში ყველაფერი ნორმალურად არის კონფიგურირებული და Qt SDK ვერსიები წარმატებულია, მაშინ პროექტი უნდა აშენდეს შემდეგი სამი ბრძანების გამოყენებით.

$ qmake -პროექტი $ qmake $ make

პირველი ბრძანება შექმნის პროექტის ფაილს. პროექტის ფაილს აქვს სუფიქსი .პრო. ვინდოუსის კონტექსტში სწორი იქნება ვთქვათ „გაფართოება პროცნებები ფაილის სახელის სუფიქსიდა ფაილის გაფართოებანიშნავს სრულიად განსხვავებულ ნივთებს, თუმცა ისინი მსგავსია. დარწმუნდით, რომ გამოიყენეთ იგი სწორად.

მეორე ბრძანებამ უნდა შექმნას კომპილაციის სკრიპტის ფაილი - Makefile. მესამე ბრძანებამ უნდა აწარმოოს კომპილაციის სკრიპტი, რომელიც უნდა აწარმოოს შესრულებადი აპლიკაციის ფაილი.

თუ ეს არ მოხდა, მაშინ ჩვენ შევეცდებით პრობლემის პოვნა.

გახსენით პროექტის ფაილი. შეეცადეთ იპოვოთ იქ შემდეგი ხაზი.

QT += gui

თუ ასეთი ხაზი არ არის, მაშინ უნდა დაამატოთ იგი, წინააღმდეგ შემთხვევაში, SDK ვერსიიდან გამომდინარე, პროექტი შეიძლება აღიქმებოდეს როგორც კონსოლის პროექტი და GUI კლასის სათაურის ფაილების ბილიკები მასში არ იქნება ჩართული. ეს გამოიწვევს კომპილაციის შეცდომებს, სადაც ნათქვამია, რომ სათაურის ფაილები ვერ მოიძებნა.

გაითვალისწინეთ, რომ თუ საქმე გაქვთ Qt SDK 5 ვერსიასთან, მაშინ ეს განმარტება ასევე უნდა შეიცავდეს ჯგუფს ვიჯეტებიროგორც ქვემოთაა ნაჩვენები.

QT += gui ვიჯეტები

QtCreator-ისგან GUI აპლიკაციის შაბლონის შექმნის მაგალითი

გახსენით QtCreator. ახალი პროექტის შესაქმნელად გაუშვით პროექტის შექმნის ოსტატი მენიუდან "ფაილი-> ახალი ფაილი ან პროექტი...". ფანჯარაში, რომელიც იხსნება ოსტატის პირველ გვერდზე, მოგეთხოვებათ აირჩიოთ შაბლონი მომავალი პროექტისთვის. "Application" პროექტის ჯგუფისთვის აირჩიეთ "Qt GUI Application" ვარიანტი და დააწკაპუნეთ ღილაკზე "არჩევა" ოსტატის შემდეგ გვერდზე გადასასვლელად.

პროექტის შექმნის ოსტატის მეორე გვერდზე თქვენ მოგეთხოვებათ აირჩიოთ პროექტის სახელი და მისი მდებარეობის დირექტორია. მითითებული პროექტის სახელის გამოყენებით შეიქმნება ქვედირექტორია, რომელშიც განთავსდება პროექტის ფაილები. ქვედირექტორი შეიქმნება მითითებულ განთავსების დირექტორიაში. ამრიგად, პროექტის სახელი უნდა განისაზღვროს იმ წესებით, რომლებსაც დირექტორის სახელი უნდა დაემორჩილოს. თუმცა, პრობლემების თავიდან ასაცილებლად, არ გამოიყენოთ რუსული ასოები და ინტერვალი. გამოიყენეთ ინგლისური ასოები, რიცხვები და ხაზები და ტირეები (მინუს ნიშანი). დაე, ჩვენი პროექტი ეწოდოს აპლიკაცია 1. დავწეროთ სტრიქონში სახელი, ხოლო პროექტის დირექტორიას შერჩევის ხაზში მივუთითებთ დირექტორიას, სადაც გავაგრძელებთ პროექტების შექმნას Qt-ზე. თავიდან უნდა იქნას აცილებული რუსული ასოებითა და ინტერვალით ბილიკები. ადრე თუ გვიან მათ შეიძლება პრობლემები შეუქმნან. თუ დაგჭირდებათ ამ ბილიკის დამახსოვრება მომდევნო ჯერზე, მონიშნეთ ჩამრთველი „გამოიყენე როგორც ნაგულისხმევი პროექტის ადგილმდებარეობა“. დააჭირეთ ღილაკს "შემდეგი" ოსტატის შემდეგ გვერდზე გადასასვლელად.

პროექტის შექმნის ოსტატის მესამე გვერდზე თქვენ მოგეთხოვებათ აირჩიოთ Qt SDK QtCreator-ში ნაპოვნი და დარეგისტრირებული სიიდან. აირჩიეთ Qt4 ვარიანტი. არჩეული SDK ვერსიისთვის, თქვენ უნდა განსაზღვროთ პროექტის აშენების პროფილები. შემოთავაზებულია "გამოშვება" და "გამართვა" კონსტრუქცია "გამოშვება" არ შეიცავს გამართვის სიმბოლოებს შესრულებად ფაილში და რეკომენდირებულია რეალურ გამოყენებაში გადასატანად. ყველა სხვა შემთხვევაში უფრო მოსახერხებელია "Debug" build-ის გამოყენება. ამჟამინდელ მაგალითში, შეკრების არჩევანს მნიშვნელობა არ აქვს. შეგიძლიათ ორივე პროფილი ჩართული დატოვოთ. პროფილის სახელის მარჯვნივ არის შეყვანის ველი, რომელშიც იწერება ბილიკი, რომლის გასწვრივ შესრულდება შესაბამისი შეკრება. ხშირად ეს ბილიკები რედაქტირდება სხვადასხვა ტრადიციების საფუძველზე. ჩვენს მაგალითში შეგვიძლია ეს ბილიკები უცვლელად დავტოვოთ. დააჭირეთ ღილაკს "შემდეგი" ოსტატის შემდეგ გვერდზე გადასასვლელად.

პროექტის შექმნის ოსტატის მეოთხე გვერდზე თქვენ მოგეთხოვებათ აირჩიოთ კლასის სახელი პროექტის ძირითადი ფორმისთვის, საბაზისო კლასი, საიდანაც უნდა იყოს მემკვიდრეობით მიღებული პროექტის მთავარი ფორმა და ფაილების სახელები, სადაც ინტერფეისი. და განთავსდება ძირითადი ფორმის შექმნილი კლასის განხორციელება. გარდა ამისა, გვერდზე უნდა იყოს მითითებული, გამოყენებული იქნება თუ არა ვიზუალური ფორმის დიზაინი. ვინაიდან ჩვენ არ გამოვიყენებთ ვიზუალურ დიზაინს, უნდა დავრწმუნდეთ, რომ „ფორმის გენერირება“ მონიშნული არ არის.

New Project Wizard-ის მეოთხე გვერდზე ყველაზე საინტერესოა საბაზისო კლასის არჩევა ფორმის კლასის შესაქმნელად. შემოთავაზებულია სამი ვარიანტი.

  1. QMainWindow- უმეტეს შემთხვევაში, ყველაზე შესაფერისი არჩევანი. ამ კლასიდან მემკვიდრეობით ვიღებთ მზა ინსტრუმენტებს მენიუს, სტატუსის ზოლისა და ცენტრალური ველის განთავსებისთვის, რომელიც შეიძლება განხორციელდეს როგორც SDI (Single Document Interface) სტილში, ასევე MDI (Multi Document Interface) სტილში.
  2. QWidget— ეს კლასი უმარტივესი ვიჯეტია. Qt ტერმინოლოგიაში, ეს არის უმარტივესი ელემენტი, რომელთანაც დაკავშირებულია ეკრანზე რაიმე სახის გრაფიკული არე. როგორც ძირითადი ფანჯრის საბაზო კლასი, იგი გამოიყენება, როგორც წესი, მარტივი ერთფორმიანი აპლიკაციების შექმნისას და შესანიშნავია საწყისი „სტუდენტური“ მიზნებისთვის, იმის გამო, რომ ის არ შეიცავს არაფერს „ზედმეტს“.
  3. QDialog- საბაზისო კლასი მოდალური დიალოგური ფანჯრების შესაქმნელად.

ჩვენი მაგალითისთვის ჩვენ ავირჩევთ საბაზისო კლასად, უმარტივესი ვარიანტია QWidget. ფორმის ძირითადი კლასის და იმ ფაილების სახელები, სადაც განთავსდება მისი ინტერფეისი და განხორციელება, შეიძლება დარჩეს ნაგულისხმევ მნიშვნელობებად. დააჭირეთ ღილაკს "შემდეგი" ოსტატის შემდეგ გვერდზე გადასასვლელად.

პროექტის შექმნის ოსტატის მეხუთე გვერდი საშუალებას გაძლევთ განსაზღვროთ შექმნილი პროექტის ურთიერთობა უკვე ღია პროექტებთან და მიუთითოთ ნებისმიერი ხელმისაწვდომი პროექტის ვერსიის კონტროლის სისტემის არჩევანი. მიმდინარე მაგალითში ჩვენ არ გვაინტერესებს ეს ფუნქციები, ამიტომ ჩვენ უნდა დავასრულოთ ოსტატი ღილაკზე "დასრულება" დაწკაპუნებით.

IN სხვადასხვა ვერსიები QtCreator პროექტის შექმნის ნაბიჯები შეიძლება ოდნავ განსხვავებული იყოს, მაგრამ არსებითად აქ არის ძირითადი პუნქტები, რომლებიც უნდა გესმოდეთ GUI პროექტის შექმნისას. მიმდინარე აღწერა გაკეთდა QtCreator ვერსიის 2.7.0 საფუძველზე.

QtCreator-ში New Project Wizard-ის დასრულების შემდეგ გაიხსნება ხედი შექმნილი პროექტით. გაუშვით პროექტი თქვენი განვითარების გარემოს პარამეტრების შესამოწმებლად. თუ ყველაფერი რიგზეა, მაშინ შექმნილი პროექტის შაბლონი უნდა შედგეს და გაუშვას. პროექტის ნორმალურად დასაწყებად, შეგიძლიათ დააჭიროთ ღილაკს მწვანე სამკუთხედით, რომელიც მდებარეობს ინსტრუმენტთა პანელზე. ღილაკი მწვანე სამკუთხედის გამოსახულებით ხოჭოსთან ერთად ასრულებს გამართვის რეჟიმის გაშვების ფუნქციებს. ამ შემთხვევაში, თუ პროექტში დაყენებულია წყვეტის წერტილები, მაშინ როდესაც ისინი მიიღწევა, შესრულება გაშვებული აპლიკაციაშეჩერდება და ხაზი, სადაც გაჩერება გაკეთდა, მონიშნული იქნება გამართვის რედაქტორში.

QtCreator შესამჩნევად განსხვავდება დიზაინით სხვა განვითარების გარემოსგან. თუმცა მისი დიზაინი საოცრად ერგონომიულია. სხვა საკითხებთან ერთად, ფართო ეკრანების ეპოქაში, განვითარების გარემოს მთავარ ფანჯარაში მარცხნივ განთავსებული ხელსაწყოების პანელი ძალიან მომგებიანი გამოიყურება. ინსტრუმენტთა პანელის ბოლოში, როგორც უკვე აღვნიშნეთ, არის აპლიკაციის გაშვების ღილაკები, ხოლო ზევით არის ღილაკები განვითარების გარემოს მთავარი ფანჯრისთვის ჩანართების არჩევისთვის. მოდით შევხედოთ ძირითადი ჩანართების ჩამონათვალს.

  • "მოგესალმებით" - პროექტის შერჩევა
  • "რედაქტირება" - პროგრამის რედაქტირება.
  • „გამართვა“ - პროექტის გამართვა. მოყვება ობიექტების მონიტორინგისთვის საჭირო ფანჯრები.
  • „პროექტები“ — განვითარების გარემოში ჩატვირთული პროექტების პარამეტრები. თქვენ უნდა ყურადღებით შეისწავლოთ ამ ჩანართზე წარმოდგენილი ვარიანტები.
  • "ანალიზი" - პროექტების ანალიზი სპეციალური ხელსაწყოების გამოყენებით შესრულების შეფერხებებისა და მეხსიერების გაჟონვის პრობლემების გამოსავლენად.
  • "დახმარება" ინტეგრირებული დახმარების ფანჯარა. შეიძლება გირჩევნიათ დამოუკიდებელ დახმარების აპლიკაციასთან, QtAssistant-თან მუშაობა.

აპლიკაციის ფანჯარაში ვიჯეტების განთავსების მარტივი მაგალითი

ავიღოთ პროექტი, რომელიც შევქმენით წინა განყოფილებაში QtCreator განვითარების გარემოს ოსტატის გამოყენებით. შექმნილი პროექტი მოიცავს შემდეგ ფაილებს.

  • app1.pro- პროექტის ფაილი
  • მთავარი.cppვიჯეტი.თ და ვიჯეტი.cpp./li>
  • ვიჯეტი.თ- ძირითადი აპლიკაციის ფანჯრის კლასის ინტერფეისი.
  • ვიჯეტი.cpp— ძირითადი აპლიკაციის ფანჯრის კლასის განხორციელება.

თქვენს პროექტში ფაილის სახელები შეიძლება ოდნავ განსხვავებული იყოს. ეს შეიძლება იყოს ან იმიტომ, რომ თქვენ პირდაპირ მიუთითეთ ისინი სხვაგან პროექტის შექმნისას, ან QtCreator-ის თქვენი ვერსიის ნაგულისხმევი მნიშვნელობები განსხვავებულია.

მოდით გავხსნათ პროგრამის ძირითადი ფანჯრის განხორციელების ფაილი - ვიჯეტი.cpp. მოდით შევცვალოთ იგი შემდეგ მაგალითში წარმოდგენილი მდგომარეობით. გთხოვთ გახსოვდეთ, რომ ხაზის ნომრები მოცემულია მხოლოდ კომენტარის მოხერხებულობისთვის.

01. #შეიცავს 02. #შეიცავს 03. #შეიცავს 04. 05. #include "widget.h" 06. 07. Widget::Widget(QWidget *parent) 08. : QWidget(parent) 09. ( 10. setWindowTitle(tr("Hello World!!!")); 11. setMinimumSize(200, 80. 13. QLabel * plb = new QLabel(tr("Test"), this * ple = new QLineEdit(this); , 80, 24); ~ვიჯეტი() 24. ( 25. 26. )

სტრიქონები 01-03 მოიცავს ფაილებს ინტერფეისით შემდეგი ვიჯეტის კლასებისთვის.

  1. QLabel- ეტიკეტის კლასი. ხშირად გამოიყენება სტატიკური ტექსტური ინფორმაციის განთავსებისთვის. ესმის ზოგიერთი HTML ტეგი ფორმატირებისთვის. შეიძლება გამოყენებულ იქნას სურათის სტატიკურად დასაყენებლად. მაგალითად, ფაილიდან სურათით. მემკვიდრეობით მიღებული QFrame, ასე რომ, მისი მორგება შესაძლებელია სხვადასხვა ზღურბლზე (საზღვრებზე).
  2. QLineEdit— კლასი ერთსტრიქონიანი ტექსტური ინფორმაციის შეყვანის ველების შესაქმნელად.
  3. QPushButton- ღილაკების კლასი. ყველაზე ხშირად გამოიყენება სიგნალის დამუშავებისთვის დააწკაპუნეთ ()- დააჭირეთ ღილაკს.

კლასის კონსტრუქტორი კორპუსი ვიჯეტიშეიცავს ორ ხაზს ფანჯრის ატრიბუტების დასაყენებლად (ხაზები 10-11) და 8 სტრიქონი ფანჯრის ველზე სამი სხვა ვიჯეტის შესაქმნელად და განთავსებისთვის (ხაზები 13-20).

ფანჯრის ატრიბუტების დაყენება შედგება ბრძანებისგან, რომ დააყენოთ აპლიკაციის ფანჯრის სახელი და აპლიკაციის ფანჯრის მინიმალური ზომა. მინიმალური ზომის დასაყენებლად გამოიყენება მეთოდი, რომელიც იღებს ფანჯრის სიგანეს და სიმაღლეს პიქსელებში.

ხაზი 13 შეიცავს QLabel კლასის ინსტანციის შექმნას. ობიექტი იქმნება დინამიურად ახალი ოპერატორის გამოყენებით. ობიექტის შესაქმნელად გამოიყენება კონსტრუქტორი, რომლის პირველი პარამეტრი განსაზღვრავს სტრიქონს, რომელსაც შექმნილი ობიექტი უნდა წარმოადგენდეს. ამ კონსტრუქტორის მეორე პარამეტრში უნდა იყოს მითითებული ობიექტის მისამართი, რომელიც გახდება შექმნილი ლეიბლის ობიექტის მფლობელი. მფლობელის მისამართი დაყენებულია ეს. C++ ენის წესების მიხედვით, ესარის მაჩვენებელი ობიექტის, რომლის ფარგლებშიც იგი გამოიყენება. ანუ ამ კონტექსტში ის არის კლასის შექმნილი ინსტანციის მაჩვენებელი ვიჯეტი. ამრიგად, მე-13 სტრიქონი ქმნის ლეიბლის კლასის ობიექტს, რომელიც უნდა წარმოადგენდეს მითითებულ ტექსტს და რომლის მფლობელიც მინიჭებულია მიმდინარე ობიექტზე.

ახლა დროა ვისაუბროთ საკუთრების ჯაჭვებზე, რომლებიც დანერგილია Qt კლასის სისტემაში ობიექტების განადგურების პრობლემის გადასაჭრელად მეხსიერების შემთხვევითი გაჟონვის თავიდან ასაცილებლად. უნდა გვახსოვდეს, რომ დინამიურად შექმნილი ობიექტები, ე.ი. ოპერატორის გამოყენებით ახალი, განლაგებულია მეხსიერების სპეციალურ ზონაში ე.წ გროვადა რომლებიც ცხოვრობენ გროვაზე, სანამ ოპერატორის მიერ აშკარად არ განადგურდებიან წაშლა. თუ პროგრამისტი არ აკონტროლებს ობიექტების განადგურებას, რომლებიც არასაჭირო გახდა და არ მოუწოდებს ოპერატორს მათი განადგურებისთვის წაშლა, მაშინ ეს ხდება აპლიკაციაში მეხსიერების გაჟონვის მიზეზი, რაც სერიოზულ პრობლემას წარმოადგენს რიგი პროგრამირების ენებისთვის, რომლებიც მოიცავს C++ ენას.

არსებობს რამდენიმე ცნობილი სქემა დინამიურად შექმნილი ობიექტების განადგურების ავტომატურად თვალყურის დევნებისთვის. ერთ-ერთი მათგანია ჭკვიანი პოინტერების გამოყენება, რაც შემდგომში უნდა განიხილებოდეს. კიდევ ერთი გზაა საკუთრების ჯაჭვების შექმნა, რაზეც ახლა განვიხილავთ. მესამე გზა არის ნაგვის შეგროვების ქვესისტემის შექმნა, რომელიც უნდა აკონტროლებდეს არასაჭირო ობიექტებს და გაანადგუროს ისინი. ეს უკანასკნელი მეთოდი, ტრადიციული მრავალი თანამედროვე ენის ბირთვისთვის, პრაქტიკულად არ გამოიყენება C++-ში. პირველი ორი მეთოდი ბევრად უფრო პოპულარულია C++ ენის ტრადიციებში.

ასე რომ, საკუთრების ჯაჭვები ახორციელებენ შემდეგ მარტივ იდეას. იქმნება ობიექტი, რომლის განადგურების მონიტორინგს ჩვენ ვიღებთ ვალდებულებას. უმარტივესი გზაა ასეთი ობიექტის შექმნა სტატიკური განსაზღვრებით და შემდეგ ის ავტომატურად განადგურდება, როდესაც პროგრამის შესრულება მიაღწევს განცხადების ბლოკის ბოლოს (...), რომელშიც ის იყო განსაზღვრული. შემდეგი, როდის დინამიური შექმნასხვა ობიექტებისთვის, ჩვენ მათ მფლობელს მივანიჭებთ ობიექტებს. მფლობელების პასუხისმგებლობა მოიცავს საკუთრებაში არსებული ობიექტების განადგურებას საკუთარი დესტრუქტორის სხეულში. შეგახსენებთ, რომ დესტრუქტორი არის სპეციალური მეთოდი, რომელსაც ეწოდება ობიექტის განადგურების დროს. ამრიგად, შესაძლებელია პირველი ობიექტის მიმართ ისეთი საკუთრების ჯაჭვის აგება, რომლის ყველა ელემენტი ავტომატურად განადგურდება პირველი ობიექტის განადგურებისას. ასეთი სქემის ორგანიზებისას საჭიროა მხოლოდ სწორად გაითვალისწინოთ ობიექტის სიცოცხლის ხანგრძლივობა, რომელიც დანიშნულია სხვა ობიექტის მფლობელად, რათა ობიექტები ნაადრევად არ განადგურდეს.

ეს არის ზუსტად Qt კლასის სისტემაში დანერგილი საკუთრების სქემა. ამ ბიბლიოთეკიდან მრავალი კლასის შექმნისას, შეგიძლიათ გამოიყენოთ კონსტრუქტორი, რომლის ერთადერთი ან ბოლო პარამეტრი აღებს მაჩვენებელს ობიექტზე, რომელიც მინიჭებულია როგორც შექმნილი ობიექტის მფლობელი. ეს პარამეტრი აღწერილია, როგორც პარამეტრი ნაგულისხმევი მნიშვნელობით, რომელიც განისაზღვრება როგორც ნული. ამრიგად, თუ მფლობელის მისამართი არ არის მითითებული, მაშინ პარამეტრი დაყენებულია ნულზე და ასეთი ობიექტის საკუთრების სქემა გამორთულია. ამ შემთხვევაში, თქვენ უნდა გახსოვდეთ ასეთი ობიექტის მკაფიოდ განადგურება.

საკუთრების ჯაჭვის სქემების დანერგვისას, ზოგიერთი ბიბლიოთეკა იყენებს პარამეტრს ე.წ მფლობელი, რომელიც ინგლისურიდან ითარგმნება როგორც მფლობელი. თუმცა Qt ბიბლიოთეკაში ამ პარამეტრს ეძახიან მშობელი, რომელიც ინგლისურიდან ითარგმნება როგორც მშობელი. შედეგად, ზოგიერთ ახალბედას გაუგებრობა აქვს იმის გამო, რომ კონცეფცია "მშობელი" ტრადიციულად ეხება მემკვიდრეობით ჯაჭვებს OOP-ში, მაგრამ მემკვიდრეობის ჯაჭვებსა და საკუთრების ჯაჭვებს საერთო არაფერი აქვთ. იყავით ფრთხილად და ნუ გახდებით ამ საკითხში მცდარი წარმოდგენების მსხვერპლი.

კიდევ ერთხელ დავუბრუნდეთ მე-13 სტრიქონს. იქ შევქმენით ობიექტი, რომლის მფლობელი მინიჭებულია აპლიკაციის მთავარი ფანჯრის მიმდინარე ობიექტზე. ცვლადი plb, რომელიც ინახავს შექმნილი ობიექტის მისამართს, ავტომატურად განადგურდება კონსტრუქტორის კოდის დასასრულის მიღწევისას. თუმცა, ობიექტი, რომელიც გამოყოფილი იყო მეხსიერებაში, გააგრძელებს სიცოცხლეს და იცხოვრებს მანამ, სანამ მთავარი აპლიკაციის ფანჯრის ობიექტი არ განადგურდება. მთავარი ფანჯრის ობიექტის განადგურება ავტომატურად გაანადგურებს ყველა ობიექტს, რომელსაც ფანჯრის ობიექტი ფლობს.

მე-14 სტრიქონზე ჩვენ ვწვდებით გეომეტრიის ატრიბუტების დაყენების მეთოდს, რომელიც განსაზღვრავს მორგებული ობიექტის განლაგებას მის მფლობელთან მიმართებაში. პირველი და მეორე მნიშვნელობები მიუთითებს ჰორიზონტალურ და ვერტიკალურ კოორდინატებზე ობიექტის ზედა მარცხენა კუთხისთვის. მესამე და მეოთხე მნიშვნელობები მიუთითებს მორგებული ობიექტის სიგანესა და სიმაღლეზე.

თუ თქვენ დარწმუნდით, რომ წინა განყოფილებაში შექმნილი მაგალითი აწყობილი და შეცდომის გარეშე მუშაობდა, მაშინ ეს მაგალითიც, რომელიც წინა ნაწილის გაგრძელებაა, უნდა გაუშვათ.

გამოყენება ამ აპლიკაციასშეგიძლიათ ექსპერიმენტი გააკეთოთ აპლიკაციის გაშვების ვარიანტებით. ამის გაკეთების ყველაზე მარტივი გზა კონსოლშია. გადადით აპლიკაციის შექმნის დირექტორიაში და მიჰყევით შემდეგ ვარიანტებს, რომ გაუშვათ აპლიკაცია პარამეტრებით. თითოეულ გაშვებაში უნდა იყოს შესამჩნევი განსხვავება ვიჯეტების დახატვის სტილში.

$ ./app1 -style=მოტივი $ ./app1 -style=windows $ ./app1 -style=პლატინი

ამ მაგალითში განაცხადის შესრულებადი ფაილი მითითებულია სახელით აპლიკაცია 1. შესაძლებელია, რომ თქვენს შემთხვევაში შესრულებად ფაილს სხვა სახელი ჰქონდეს. საოპერაციოში Windows სისტემა, შესრულებად ფაილებს აქვთ გაფართოება exe. გარდა ამისა, Windows ოპერაციულ სისტემაში შეგიძლიათ გაუშვათ შესრულებადი ფაილი მიმდინარე დირექტორიადან შედარებითი ბილიკის მითითების გარეშე, ე.ი. მითითების გარეშე ( ./ ) - წერტილის სიმბოლო არის მიმდინარე დირექტორიას სინონიმი, ხოლო წინ დახრილი სიმბოლო არის გამყოფი სიმბოლო ფაილის ბილიკში. ასევე, გახსოვდეთ, რომ დოლარის სიმბოლო არის სტანდარტული მოთხოვნის სიმბოლო *nix კონსოლში ჩვეულებრივი მომხმარებლისთვის და არ საჭიროებს აკრეფას ბრძანების ნაწილად. Windows-ის კონსოლში მოთხოვნის სიმბოლო ჩვეულებრივ არის კუთხის ფრჩხილის სიმბოლო ( > ).

გაშვების ვარიანტების დაზუსტება ასევე შესაძლებელია QtCreator-ის განვითარების გარემოდან აპლიკაციის გაშვებისას. ამისათვის დააწკაპუნეთ ინსტრუმენტთა მარცხენა პანელზე არსებულ ხატულაზე პროექტები. შესაბამისი პარამეტრების ჩანართი გაიხსნება. ფანჯრის ზედა ნაწილში შეგიძლიათ იხილოთ ჩანართების იერარქიული სისტემა. ზედა დონის ჩანართები განსაზღვრავს პროექტს, რადგან მრავალი პროექტი შეიძლება იყოს გახსნილი განვითარების გარემოში. ჩანართების შემდეგი დონე, სხვა საკითხებთან ერთად, უნდა შეიცავდეს ჩანართს აშენება და გაშვება, რომელიც ჩვენ გვჭირდება. ამ ჩანართში, თქვენ ირჩევთ Qt SDK ვერსიას, იმ შემთხვევაში, თუ თქვენ აშენებთ პროექტს ერთდროულად რამდენიმე ვერსიისთვის. თუ თქვენ აწყობთ პროექტს ერთი ვერსიისთვის, მაშინ არჩევანი შედგება ერთი ელემენტისგან. Qt SDK ვერსიის შერჩევის ვიჯეტის შიგნით არის ორი სტილიზებული ღილაკი მომრგვალებული კიდეებით - ღილაკები აშენებადა გაიქეცი. დააჭირეთ ღილაკს გაიქეციპარამეტრების შესაბამისი ჯგუფის შესარჩევად. იქ, ამავე სახელწოდების პარამეტრულ ჯგუფში გაიქეცითქვენ იპოვით ერთი ხაზის შეყვანის ველს ეტიკეტის საპირისპიროდ არგუმენტები. ეს არის ჩვენი არჩევანის საბოლოო მიზანი. დავწეროთ იქ შემდეგი სტრიქონი.

სტილი=მოტივი

გაუშვით აპლიკაცია. შემდეგ სცადეთ სხვა მნიშვნელობები: ფანჯრებიდა პლატინის. შეგახსენებთ, რომ კლასის ობიექტი QApplicationმხარს უჭერს რამდენიმე ათეული გაშვების პარამეტრის სიას, რომელთა შესახებაც შეგიძლიათ წაიკითხოთ შესაბამისი კლასის კონსტრუქტორების დახმარებაში.

მაგალითზე მუშაობისას გაეცანით ფონური ინფორმაციამაგალითში გამოყენებული კლასების მიხედვით. სცადეთ ფორმაში დაამატოთ ლეიბლის სხვა ეგზემპლარები, ერთი ხაზის შეყვანის ველი და ღილაკების კლასები. გარდა ამისა, შეეცადეთ წაიკითხოთ დახმარება და დაამატოთ შემდეგი კლასების ობიექტები ფორმაში.

  1. QComboBox- ჩამოსაშლელი სიის კლასი.
  2. QCheckBox— დროშის (ჩეკერის) კლასი.
  3. QTextEdit— მრავალხაზოვანი შეყვანის ველის კლასი. გამოიყენება როგორც ტექსტის რედაქტირებისთვის, ასევე წარმოდგენისთვის. შეიცავს დოკუმენტების წარმოდგენის ძალიან მდიდარ შესაძლებლობებს სპეციალური დოკუმენტების შემქმნელების ფუნქციების ცალკეულ კლასებად გამოყოფით.

გაკვეთილის დასასრულს უნდა აღინიშნოს, რომ ფორმის ველზე ობიექტების „ხისტი“ განთავსების მეთოდი, განლაგების გეომეტრიის აშკარა მითითებით, არ არის ტრადიციული და რეკომენდებულია Qt კლასის ბიბლიოთეკაში. შემდეგი გაკვეთილები განიხილავს განლაგების მენეჯერებს, რომლებიც თანამედროვე და მოსახერხებელი საშუალებებია ვიჯეტების ფორმაზე განთავსებისთვის.

პროგრამირება Qt

ნაწილი 1. შესავალი. დეველოპერის ინსტრუმენტები და ობიექტის მოდელი

შინაარსის სერია:

1. შესავალი

არსებობს Qt-ის ვერსიები unix-ის მსგავსი ოპერაციული სისტემებისთვის X Window System-ით (მაგალითად, X.Org (EN), Mac OS X და Windows OS). Qt Software ასევე პორტირებს თავის პროდუქტს მობილურ პლატფორმებზე: Embedded Linux (EN), S60 (EN) და Windows CE. Qt იძლევა დიდ შესაძლებლობებს კროს პლატფორმის განვითარებისთვის სხვადასხვა პროგრამები, არ არის აუცილებელი გრაფიკული ინტერფეისით. კერძოდ, მასზეა დაფუძნებული პოპულარული KDE დესკტოპის გარემო.

ინსტრუმენტთა ნაკრები დაყოფილია მოდულები, რომელთაგან თითოეული ცალკე ბიბლიოთეკაშია განთავსებული. საბაზო კლასები არის QtCore-ში, GUI კომპონენტები არის QtGui-ში, ქსელის კლასები არის QtNetwork-ში და ა.შ. ამრიგად, შესაძლებელია პროგრამების შედგენა იმ პლატფორმებისთვისაც კი, სადაც არ არის X11 ან სხვა თავსებადი გრაფიკული ქვესისტემა.

2. Qt-ის დაყენება

ჩვენ დაგვჭირდება Qt განვითარების გარემოს დაყენება. პროგრამული უზრუნველყოფაგანაწილებულია უფასო ლიცენზიის GPL 3.0 ან LGPL 2.1 პირობებით. მისი მიღება შეგიძლიათ http://www.qtsoftware.com/downloads (EN).

2.1. ძირითადი ბიბლიოთეკები და ინსტრუმენტები

პოპულარული GNU/Linux დისტრიბუციების საცავებს უკვე აქვთ მზა პაკეტები Qt განვითარების გარემოთი (მაგალითად, Debian, Fedora, Gentoo, Mandriva, Ubuntu). თუმცა, მომხმარებელს შეუძლია შექმნას და დააინსტალიროს ინსტრუმენტთა ნაკრები საწყისი კოდიდან.

სისტემებისთვის, რომლებიც იყენებენ X11-ს, თქვენ უნდა ჩამოტვირთოთ ფაილი qt-x11-opensource-src-4.x.y.tar.gz, სადაც 4.x.y არის უახლესი სტაბილური ვერსია. ჩვენ დავაინსტალირებთ 4.5.0 ვერსიას.

დირექტორიაში qt-x11-opensource-src-4.5.0.tar.gz ფაილით, გაუშვით შემდეგი ბრძანებები:

tar xvfz qt-x11-opensource-src-4.5.0.tar.gz cd qt-x11-opensource-src-4.5.0

Qt-ის აშენებამდე გაუშვით კონფიგურაციის სკრიპტი. მისი პარამეტრების სრული ნაკრები ნაჩვენებია ბრძანების გამოყენებით ./configure -help, მაგრამ ჩვეულებრივ შეიძლება გამოყენებულ იქნას სტანდარტული პარამეტრები.

-prefix პარამეტრი განსაზღვრავს ინსტალაციის დირექტორიას (ნაგულისხმევი არის /usr/local/Trolltech/Qt-4.5.0). ასევე არსებობს სხვადასხვა საქაღალდეებში სხვადასხვა კომპონენტის (შესრულებადი ფაილები, ბიბლიოთეკები, დოკუმენტაცია და ა.შ.) ინსტალაციის გასაღებები.

გაშვებისას, სკრიპტი მოითხოვს მომხმარებლისგან დაეთანხმოს GPL/LGPL ლიცენზიის პირობებს. აღსრულების შემდეგ

./კონფიგურაცია

თქვენ შეგიძლიათ დაიწყოთ მშენებლობა და ინსტალაცია ბრძანებების გამოყენებით:

გააკეთე და დააინსტალირე

გაითვალისწინეთ, რომ კომპილაციას დიდი დრო სჭირდება და Qt-ის ინსტალაციას შეიძლება დასჭირდეს root პრივილეგიები (ფაილები იწერება /usr/local/).

თუ მოგვიანებით დაგჭირდებათ Qt-ის ხელახლა კონფიგურაცია და აღდგენა იმავე დირექტორიაში, წაშალეთ წინა კონფიგურაციის ყველა კვალი make confclean-ის გამოყენებით ./configure ხელახლა გაშვებამდე.

გზა Qt შესრულებამდე უნდა დაემატოს PATH გარემოს ცვლადს. bash, ksh, zsh და sh ჭურვებში ეს შეიძლება გაკეთდეს შემდეგი ხაზების დამატებით ~/.profile ფაილში:

PATH=/usr/local/Trolltech/Qt-4.5.0/bin:$PATH ექსპორტის გზა

csh-ში და tcsh-ში თქვენ უნდა დაამატოთ შემდეგი ხაზი ~/.login-ში:

setenv PATH /usr/local/Trolltech/Qt-4.5.0/bin:$PATH

თუ იყენებთ სხვა გარსს, გთხოვთ, იხილოთ დოკუმენტაციის შესაბამისი განყოფილებები.

გარდა ამისა, თქვენ უნდა დაამატოთ ხაზი /usr/local/Trolltech/Qt-4.5.0/lib LD_LIBRARY_PATH ცვლადში, თუ შემდგენელი არ უჭერს მხარს RPATH-ს. ჩვენ ვიყენებთ GNU/Linux-ს და GCC (EN), ამიტომ გამოვტოვებთ ამ ნაბიჯს.

შემდეგ გამოიყენეთ qtdemo პროგრამა დემო აპლიკაციების გასაშვებად დაყენებული ხელსაწყოების ფუნქციონირების შესამოწმებლად.

2.2. SDK

ახლახან გამოჩნდა ჯვარედინი პლატფორმის განვითარების გარემო Qt Creator. სრული SDK, მათ შორის IDE (გარდა ბიბლიოთეკებისა და ძირითადი დეველოპერის ხელსაწყოებისა), შეგიძლიათ იხილოთ Qt Software ვებსაიტზე. ჩამოტვირთეთ qt-sdk-linux-x86-opensource-xxx.bin ორობითი და გაუშვით ინსტალაციის ოსტატი:

chmod +x ./qt-sdk-linux-x86-opensource-2009.01.bin ./qt-sdk-linux-x86-opensource-2009.01.bin

თუ არ აპირებთ SDK-ის დაყენებას თქვენს მთავარ დირექტორიაში, მაშინ გაუშვით ინსტალერი სუპერმომხმარებლის უფლებებით.


3. დეველოპერის ინსტრუმენტები

Qt მოიცავს დეველოპერის ინსტრუმენტებს გრაფიკული ან კონსოლის ინტერფეისით. Მათ შორის:

  • ასისტენტი არის გრაფიკული ინსტრუმენტი Qt ინსტრუმენტებისა და ბიბლიოთეკებისთვის ჰიპერტექსტის დოკუმენტაციის სანახავად.
  • დიზაინერი – გრაფიკული ინსტრუმენტი შექმნისა და აწყობისთვის მომხმარებლის ინტერფეისები Qt კომპონენტებზე დაყრდნობით.
  • qmake არის cross-platform Makefile გენერატორი.
  • moc არის მეტაობიექტის შემდგენელი (Qt გაფართოების დამმუშავებელი C++-ისთვის).
  • uic არის მომხმარებლის ინტერფეისების შემდგენელი .ui ფაილებიდან, რომლებიც შექმნილია Qt Designer-ში.
  • rcc – რესურსების შემდგენელი .qrc ფაილებიდან.
  • qtconfig არის გრაფიკული ინსტრუმენტი Qt აპლიკაციებისთვის მომხმარებლის პრეფერენციების დასაყენებლად.
  • qtdemo – იწყებს მაგალითებს და დემო პროგრამებს.
  • qt3to4 არის ინსტრუმენტი Qt 3-დან Qt 4-ში პროექტების გადატანისთვის.
  • ლინგვისტი არის აპლიკაციების ლოკალიზაციის ინსტრუმენტი.
  • pixeltool - ეკრანის ლუპა.


3.1. qmake

qmake უტილიტა გამოიყენება Makefiles-ის ავტომატურად გენერირებისთვის სხვადასხვა პლატფორმაზე.

ზოგადად, qmake არის Qt-ზე ორიენტირებული. თუ გაინტერესებთ კროს-პლატფორმული კონსტრუქციის სისტემები უფრო ფართო მიზნებისთვის, შეგიძლიათ მიმართოთ CMake-ს, რომელიც ასევე მხარს უჭერს Qt-ს.

დამწყებებმა უნდა დაიცვან qmake.

თქვენ შეგიძლიათ იპოვოთ სრული დოკუმენტაცია ამ პროგრამისთვის Qt Assistant-ში. Qt-ს ასევე გააჩნია man pages, მათ შორის qmake(1) (ჩაწერეთ ბრძანების ხაზიკაცი qmake). აქ ჩვენ შემოგთავაზებთ ძირითად მითითებებს, რომლებიც დაგეხმარებათ შექმნათ სტატიის კოდი, ისევე როგორც თქვენი მარტივი პროექტები.

მაგალითად, შევქმნათ დირექტორია myproject და დავამატოთ ფაილები hello.h, hello.cpp და main.cpp. hello.h-ში ჩვენ აღვწერთ hello() ფუნქციის პროტოტიპს:

ჩამონათვალი 1.1. პროგრამის "გამარჯობა, სამყარო!" ფუნქციების დეკლარაციები.
// hello.h void hello();

hello()-ის განხორციელება განთავსდება hello.cpp-ში:

ჩამონათვალი 1.2. პროგრამის "გამარჯობა, სამყარო!" ფუნქციების განხორციელება
// hello.cpp #include #include "hello.h" void hello() ( qDebug()<< "Hello, World!"; }

აქ qDebug() გამოიყენება გამართვის ინფორმაციის გამოსატანად. მისი ამოღება შესაძლებელია სიმბოლოს QT_NO_DEBUG_OUTPUT გამოცხადებით კომპილაციის დროს. ასევე არის ფუნქცია qWarning(), რომელიც გასცემს გაფრთხილებებს და qFatal(), რომელიც წყვეტს აპლიკაციას STDERR-ში კრიტიკული შეცდომის შეტყობინების დაბეჭდვის შემდეგ (qCritical() აკეთებს იგივეს, მაგრამ შეწყვეტის გარეშე).

სათაურის ფაილში შეიცავს დეკლარაციებს, რომლებიც ამატებენ უფრო მოსახერხებელ ოპერატორის სინტაქსს qDebug(), qWarning() და qCritical()<< . При этом между аргументами (как в случае qDebug() << a << b << c;) автоматически расставляются пробелы, поддерживается вывод многих типов C++ и Qt, а в конце автоматически добавляется перевод строки.

აპლიკაციის მთავარი კოდი (აქ ჩვენ მივყვებით main.cpp ფაილში main()-ის ჩასმის კონვენციას):

ჩამონათვალი 1.3. პროგრამის "გამარჯობა, სამყარო!" მთავარი () ფუნქცია
// main.cpp #include "hello.h" int main() ( hello(); return 0; )

პროექტის ფაილის შესაქმნელად, გაუშვით

ამის შემდეგ, myproject.pro ფაილი უნდა გამოჩნდეს დაახლოებით შემდეგი შინაარსით:

################################## # ავტომატურად გენერირებული qmake ########## # ########################### თარგი = აპლიკაცია TARGET = DEPENDPATH += . INCLUDEPATH += . # შეყვანის HEADERS += hello.h SOURCES += hello.cpp main.cpp

= ოპერატორი გამოიყენება ცვლადებისთვის მნიშვნელობების მინიჭებისთვის, += ამატებს ახალ ვარიანტს ცვლადს, -= შლის მითითებულ ვარიანტს.

TEMPLATE = აპლიკაცია ნიშნავს, რომ ჩვენ ვაშენებთ აპლიკაციას; ბიბლიოთეკისთვის გამოიყენეთ TEMPLATE = lib.

TARGET – სამიზნე ფაილის დასახელება (მიუთითეთ TARGET = foobar, რომ მიიღოთ ფუბარის შესრულებადი ფაილი).

DEPENDPATH – დირექტორიები, რომლებიც უნდა მოძებნოთ დამოკიდებულებების გადაჭრისას.

INCLUDEPATH – დირექტორიები სათაურის ფაილებით.

გაშვების შემდეგ

GNU/Linux-ში myproject.pro-ზე დაყრდნობით შეიქმნება რეგულარული Makefile:

####### კომპილირება hello.o: hello.cpp hello.h $(CXX) -c $(CXXFLAGS) $ (INCPATH) -o hello.o hello.cpp main.o: main.cpp hello.h $(CXX) -c $(CXXFLAGS) $ (INCPATH) -o main.o main.cpp ####### დააინსტალირეთ ინსტალაცია: FORCE დეინსტალაცია: FORCE FORCE:

qmake პარამეტრები გავლენას ახდენს Makefile-ის შინაარსზე. მაგალითად, qmake -Wall დაამატებს -Wall-ს კომპილატორის დროშებს – გამოაქვს ყველა გაფრთხილება.

make ბრძანების გამოყენებით, ჩვენ ვიღებთ შესრულებად ფაილს myproject, რომელიც აჩვენებს სტრიქონს "Hello, World!".

ეს სქემა შეიძლება ზედმეტად რთული ჩანდეს, მაგრამ რეალურ პროექტებში qmake ასრულებს build-ის უმეტეს ნაწილს (მაგალითად, მეტაობიექტის შემდგენელის გაშვება).

3.2. Qt შემქმნელი

ზემოთ აღწერილი ინსტრუმენტები საკმარისია აპლიკაციის განვითარებისთვის. შეგიძლიათ გამოიყენოთ თქვენი საყვარელი ტექსტური რედაქტორი, როგორიცაა GNU Emacs ან Vim. ტრადიციული IDE-ები, როგორიცაა KDevelop, ასევე მუშაობს Qt-თან.

თუმცა, არც ისე დიდი ხნის წინ Qt Software-მა გამოუშვა თავისი კროს-პლატფორმული IDE Qt Creator. მას აქვს ჩაშენებული დეველოპერის ყველა ინსტრუმენტი, რედაქტორი ხაზგასმით და კოდის შევსებით, გამართვა (გრაფიკული ინტერფეისი gdb-სთვის) და მხარდაჭერა Perforce, SVN და Git.

Qt Creator-ში მუშაობისას გამოიყენება რამდენიმე რეჟიმი, რომლებიც შეესაბამება მარცხნივ პანელის ჩანართებს. რეჟიმებს შორის სწრაფად გადართვისთვის შეგიძლიათ გამოიყენოთ კლავიშების კომბინაციები Ctrl+1, Ctrl+2 და ა.შ. ძირითადად რედაქტირების რეჟიმიშეესაბამება Ctrl+2-ს.


რედაქტორში ნავიგაციისთვის გამოიყენეთ კლავიშთა კომბინაცია Ctrl+K. მასზე დაჭერის შემდეგ, თქვენ უნდა მიუთითოთ ერთ-ერთი პრეფიქსი:

ცხრილი 1. Qt Creator-ში ნავიგაციის პრეფიქსები

პრეფიქსის შემდეგ დააჭირეთ spacebar და შეიყვანეთ შესაბამისი ინფორმაცია. მაგალითად, მიმდინარე ფაილის 93-ე სტრიქონზე გადასასვლელად, თქვენ უნდა აკრიფოთ „l 93“ (იგივე შეიძლება გაკეთდეს Ctrl+L-ის გამოყენებით), რომ გადახვიდეთ დოკუმენტაციაზე qobject_cast – „qobject_cast“ და ა.შ.

ფანჯრის ბოლოში ნაჩვენებია ველი ავტომატური შევსებით.

სურათი 5. ნავიგაციის ველი Qt Creator-ში

ცხრილი 2. კლავიატურის მალსახმობები Qt Creator-ისთვის

Ctrl+[გადადით ბლოკის დასაწყისში
Ctrl+]გადადით ბლოკის ბოლოს
Ctrl+Uაირჩიეთ ბლოკი
Ctrl+Shift+Uბლოკის არჩევის გაუქმება
Ctrl+Iბლოკის გასწორება
Ctrl+< ბლოკის ჩაკეცვა
Ctrl+>ბლოკის გაფართოება
Ctrl+/დაწერეთ კომენტარი ბლოკზე
Ctrl+Shift+ხაზის გადაადგილება
Ctrl+Shift+↓გადაიტანეთ ხაზი ქვემოთ
shift + დელSD ხაზის წაშლა

ჩაშენებული რედაქტორი ახორციელებს „ჭკვიან“ კოდის დამატებას, რომელსაც უწოდებენ Ctrl+ კლავიშთა კომბინაციით<Пробел>. სიმბოლოს ბაზა შედგენილია პროექტის სათაურის ფაილების საფუძველზე INCLUDEPATH-დან.

IDE-ში არის ცალკე განყოფილება დოკუმენტაციის წასაკითხად. დახმარების რეჟიმი. კლასზე ან მეთოდზე კონტექსტური დახმარების მისაღებად, უბრალოდ გადაიტანეთ ტექსტის კურსორი სახელზე და დააჭირეთ F1. F2 ღილაკი ასევე სასარგებლოა, რომელიც გადადის სათაურის ფაილებში განმარტებაზე.

დახმარების ან გამართვის რეჟიმიდან ძირითად რედაქტირების რეჟიმზე გადასართავად დააჭირეთ Esc. რედაქტირების რეჟიმში, Esc გადააქვს ფოკუსი დამატებითი ფანჯრებიდან (როგორიცაა კომპილაციის გამომავალი ან კონტექსტზე მგრძნობიარე დახმარება) რედაქტორზე. თუ კვლავ დააჭირეთ Esc-ს, დამატებითი ფანჯრები იხურება.

Qmake-ის მსგავსად, Qt Creator იყენებს .pro ფაილებს, ამიტომ ძველი ხელნაკეთი პროექტები ადვილად შეიძლება იყოს იმპორტირებული IDE-ში. ასევე ხელმისაწვდომია ოსტატი, რომლითაც შეგიძლიათ შექმნათ შაბლონი ახალი პროექტისთვის.

Qt Creator ამჟამად აქტიური განვითარების პროცესშია, მაგრამ თუ გსურთ კლასიკური Qt IDE, რომელიც მუშაობს სხვადასხვა პლატფორმაზე, ეს საუკეთესო ვარიანტია.

4. Qt სტილი

Qt-ში გამოიყენება CamelCasing: კლასების სახელები ჰგავს MyClassName-ს და მეთოდების სახელები ჰგავს myMethodName-ს.

უფრო მეტიც, Qt კლასის ყველა სახელი იწყება Q-ით, მაგალითად QObject, QList ან QFont.

კლასების უმეტესობას აქვს შესაბამისი სათაურის ფაილები იგივე სახელით (.h გაფართოების გარეშე), ე.ი. საჭიროა გამოიყენოს:

#შეიცავს #შეიცავს #შეიცავს

ამიტომ, სამომავლოდ ცალ-ცალკე არ განვსაზღვრავთ, სად არის დეკლარირებული ესა თუ ის კლასი.

მიღებისა და დაყენების მეთოდები თვისებები (მიმღებიდა სეტერი) დასახელებულია შემდეგნაირად: fooBar თვისების მიღება შესაძლებელია fooBar() მეთოდის გამოყენებით და დაყენება setFooBar()-ის გამოყენებით.

T fooBar() const; void setFooBar(T val);

Qt-ში საკუთარი აპლიკაციების შემუშავებისას, თქვენ უნდა დაიცვან ეს სტილი.

5. ობიექტის მოდელი

გაშვების დროს კლასებთან ეფექტური მუშაობისთვის, Qt იყენებს სპეციალურ ობიექტის მოდელს, რომელიც აფართოებს C++ მოდელს. კერძოდ, ემატება შემდეგი მახასიათებლები:

  • ხის მსგავსი ობიექტების იერარქია;
  • dynamic_cast-ის ანალოგი ბიბლიოთეკისთვის, რომელიც არ იყენებს RTTI-ს;
  • ობიექტების ურთიერთქმედება მეშვეობით სიგნალებიდა სლოტები;
  • ობიექტების თვისებები.

ბევრი ობიექტი განისაზღვრება რამდენიმე თვისების, შიდა მდგომარეობისა და სხვა ობიექტებთან კავშირების მნიშვნელობით. ისინი ინდივიდუალური ერთეულები არიან და მათთვის პირდაპირი კოპირების ოპერაციას, ისევე როგორც მონაცემთა მეხსიერებაში გაზიარებას აზრი არ აქვს. Qt-ში ეს ობიექტები მემკვიდრეობით იღებენ QObject-ის თვისებებს.

იმ შემთხვევებში, როდესაც ობიექტი უნდა განიხილებოდეს არა როგორც ერთეული, არამედ როგორც მნიშვნელობა (მაგალითად, როდესაც ინახება კონტეინერში), გამოიყენება მაჩვენებლები. ზოგჯერ ობიექტის მითითებას, რომელიც მემკვიდრეობით იღებს QObject-ს, უბრალოდ ობიექტს უწოდებენ.

ინსტრუმენტარიუმის შექმნილია ისე, რომ QObject-ისთვის და მისი ყველა შთამომავლისთვის ასლის კონსტრუქტორი და მინიჭების ოპერატორი მიუწვდომელია - ისინი გამოცხადებულია კერძო განყოფილებაში Q_DISABLE_COPY() მაკროზე:

კლასი FooBar: საჯარო QObject ( კერძო: Q_DISABLE_COPY (FooBar) );

იყავით ფრთხილად და არ გამოიყენოთ სტრუქტურა

ფუ ბარი = ფუ(ბაზ);

სხვა ობიექტები (როგორიცაა კონტეინერები და სტრიქონები) სრულად არის განსაზღვრული იმ მონაცემებით, რომლებსაც ისინი წარმოადგენენ, ამიტომ მათ შესაბამის კლასებს აქვთ მინიჭების ოპერატორი და ასლის კონსტრუქტორი. გარდა ამისა, ობიექტებს, რომლებიც წარმოადგენენ ერთსა და იმავე მონაცემებს, შეუძლიათ მათ მეხსიერებაში გამჭვირვალედ გამიჯნონ პროგრამისტისთვის.


5.1. მეტაობიექტური სისტემა

ზოგიერთი გაფართოება დანერგილია სტანდარტული C++ მეთოდების გამოყენებით, მაგრამ Qt ასევე იყენებს უფრო რთულ სინტაქსურ გაფართოებებს, ამიტომ იყენებს კოდის ავტომატურ გენერირებას.

ამ მიზნით, C++ ახორციელებს შაბლონის მექანიზმს, მაგრამ ის არ უზრუნველყოფს Qt-ის ყველა საჭირო შესაძლებლობას, ცუდად თავსებადია დინამიური ობიექტის მოდელთან და სრულად არ არის მხარდაჭერილი შემდგენელების ყველა ვერსიით.

რთულ სიტუაციებში Qt იყენებს თავის მეტაობიექტის შემდგენელი moc, რომელიც გარდაქმნის კოდს გაფართოებით სტანდარტულ C++ კოდში. იმის მითითებისთვის, რომ კლასი იყენებს მეტაობიექტის შესაძლებლობებს (და ამიტომ უნდა დამუშავდეს moc-ის მიერ), Q_OBJECT მაკრო უნდა იყოს მითითებული კერძო განყოფილებაში.

თუ შეხვდებით უცნაურ კომპილაციის შეცდომებს იმის შესახებ, რომ კლასს არ აქვს განსაზღვრული კონსტრუქტორი, ან არ აქვს ვირტუალური ფუნქციის ცხრილი (vtbl), სავარაუდოდ დაგავიწყდათ moc-ის მიერ გენერირებული კოდი. ეს ჩვეულებრივ ხდება, თუ Q_OBJECT მაკრო არ არის მითითებული.

შეცდომების თავიდან ასაცილებლად, უმჯობესია გამოიყენოთ Q_OBJECT ყველა კლასში, რომელიც მემკვიდრეობით იღებს QObject-ს (ირიბად ან პირდაპირ).

დინამიური მიდგომის გამოყენება დაკავშირებულია შესრულების გარკვეულ დანაკარგებთან შედარებით სტატიკურთან შედარებით, მაგრამ ეს ზედნადები შეიძლება იყოს უგულებელყოფილი, თუ მიღებული სარგებელი იქნება გათვალისწინებული.

სხვა საკითხებთან ერთად, მეტა-ობიექტის კოდი ამატებს მეთოდს

ვირტუალური const QMetaObject* QObject::metaObject() const;

რომელიც უბრუნებს მაჩვენებელს ობიექტის მეტა ობიექტს.

სიგნალები, სლოტები და თვისებები დაფუძნებულია მეტა-ობიექტის სისტემაზე.

QObject-ისგან მემკვიდრეობის მიღებისას, გაითვალისწინეთ moc-ის მიერ დაწესებული შეზღუდვები:

  1. მრავალჯერადი მემკვიდრეობით, QObject-ის შთამომავალი უნდა იყოს პირველი და ერთადერთი პირველი მემკვიდრეობით მიღებული კლასი: კლასი MyClass: public QObject, public Foo, public Bar ( // ... );
  2. ვირტუალური მემკვიდრეობა არ არის მხარდაჭერილი QObject-ით.

5.2. qobject_cast

QObject-ის დინამიურად გადასაცემად გამოიყენეთ ფუნქცია

T qobject_cast(QObject *object);

ის მუშაობს როგორც სტანდარტული dynamic_cast ოპერაცია C++-ში, მაგრამ არ საჭიროებს RTTI მხარდაჭერას.

მოდით გვქონდეს კლასი MyClass1, მემკვიდრეობით QObject-დან და MyClass2, მემკვიდრეობით MyClass1-დან:

#შეიცავს კლასი MyClass1: საჯარო QObject ( Q_OBJECT საჯარო: MyClass1(); // ... ); კლასი MyClass2: საჯარო MyClass1 ( Q_OBJECT საჯარო: MyClass2(); // ... );

დინამიური ჩამოსხმა ილუსტრირებულია შემდეგი კოდით:

QObject *a = ახალი MyClass2; MyClass1 *b = qobject_cast (ა); MyClass2 *c = qobject_cast (ბ);

ეს ოპერაციები სწორად იმუშავებს გაშვების დროს.

როგორც dynamic_cast-ის შემთხვევაში, მსახიობების შედეგის შემოწმება შესაძლებელია:

თუ (b = qobject_cast (ა)) (// ...)

მეტაობიექტის სისტემა ასევე საშუალებას გაძლევთ შეამოწმოთ მემკვიდრეობით თუ არა კლასს MyClass1:

if (a->მემკვიდრეობს("MyClass1")) (b = static_cast (ა); //...)

თუმცა, უპირატესობა ენიჭება წინა ვარიანტს qobject_cast-ით.

5.3. ობიექტი ხეები

კლასების ობიექტები, რომლებიც მემკვიდრეობით იღებს QObject-ს, შეიძლება ორგანიზებული იყოს ხის სტრუქტურაში. როდესაც ობიექტი წაიშლება, Qt წაშლის მას ბავშვის ობიექტები, რომელიც თავის მხრივ წაშლის მათი ბავშვის ობიექტებს და ა.შ. სხვა სიტყვებით რომ ვთქვათ, ობიექტის წაშლა წაშლის მთელ ქვეხეს, რომლის ფესვიც ის არის.

მოდით გვქონდეს კლასები ClassA და ClassB:

ჩამონათვალი 2.1. MyClass დეკლარაცია პროგრამისთვის, რომელიც აჩვენებს, თუ როგორ იქმნება და წაიშლება ობიექტები
// myclass.h #include კლასი MyClass: საჯარო QObject ( საჯარო: MyClass (char id, QObject *parent = 0); ~MyClass(); private: char id_; );
ჩამონათვალი 2.2. MyClass მეთოდების განსაზღვრა პროგრამისთვის, რომელიც აჩვენებს, როგორ იქმნება და წაიშლება ობიექტები
// myclass.cpp #include #შეიცავს #include "myclass.h" MyClass::MyClass (char id, QObject *parent) : QObject(მშობელი), id_(id) (qDebug()<< "+" >> id_; ) MyClass::~MyClass() ( qDebug()<< "-" >> id_; )

აქ მშობელი ობიექტი დაყენებულია QObject კონსტრუქტორში:

QObject::QObject(QObject *მშობელი = 0);

მისი დაყენება შეიძლება მოგვიანებით setParent() მეთოდის გამოყენებით და მოძიება parent()-ის გამოყენებით:

void QObject::setParent(QObject *parent);
QObject* QObject::parent() const;

თუ თქვენ შექმნით ერთ-ერთ ობიექტს A და B სტეკზე, მაშინ შეიქმნება ჯერ A, შემდეგ B. C++ სტანდარტის შესაბამისად, წაშლა ხდება საპირისპირო თანმიმდევრობით - ჯერ B, შემდეგ A:

ჩამონათვალი 2.3. MyClass ინსტანციების შექმნა Stack-ზე
// main.cpp #include "myclass.h" int main() ( MyClass a ("A"); MyClass b ("B"); return 0; )

თუ თქვენ შექმნით B გროვაზე და მიაკუთვნებთ მას A-ს შვილად, მაშინ B ავტომატურად წაიშლება A-სთან ერთად:

ჩამონათვალი 2.4. MyClass კლასის A ინსტანციის შექმნა სტეკზე და B მაგალითის გროვაზე A-ს შვილი
// main.cpp #include "myclass.h" int main() ( MyClass a ("A"); MyClass *b = new MyClass ("B", &a); return 0; )

ანალოგიურად უფრო რთული ხეებისთვის:

სურათი 8. მრავალ დონის ობიექტის ხის მაგალითი
ჩამონათვალი 2.5. დასტაში ფესვგადგმული ობიექტების მრავალდონიანი ხე
// main.cpp #include "myclass.h" int main() ( MyClass a ("A"); MyClass *b = ახალი MyClass ("B", &a); MyClass *c = ახალი MyClass ("C", &a MyClass *d = new MyClass("D", c)

A-ს წაშლის შემდეგ, მთელი ხე წაიშლება.

ამრიგად, პროგრამისტმა უნდა შექმნას ობიექტები გროვაზე და დააყენოს შესაბამისი იერარქიები, ხოლო Qt ზრუნავს მეხსიერების მართვაზე.

თუ ობიექტი და მისი ბავშვები იქმნება დასტაზე, წაშლის ამ ბრძანებამ შეიძლება გამოიწვიოს შეცდომები.

int main() ( MyClass b ("B"); MyClass a ("A"); b.setParent(&a); // ... return 0; )

აქ, სკოპიდან გასვლისას, პირველი ობიექტი A წაიშლება, რადგან ის იყო ბოლო შექმნილი. ამ შემთხვევაში Qt ასევე წაშლის თავის შვილობილ ობიექტს B. მაგრამ შემდეგ მოხდება B წაშლის მცდელობა, რაც გამოიწვევს შეცდომას.

წინააღმდეგ შემთხვევაში, პრობლემა არ იქნება, რადგან QObject დესტრუქტორის გამოძახებისას ობიექტი ამოიღებს თავს მშობელი ობიექტის შვილობილი ობიექტების სიიდან:

int main() ( MyClass a ("A"); MyClass b ("B", &a); // ... return 0; )

ზოგადად, ბავშვის ობიექტები უნდა იყოს გამოყოფილი გროვაზე.

თითოეულ QObject-ს აქვს objectName თვისება, რომლის წვდომა ხდება მეთოდების გამოყენებით

QString objectName() const; void setObjectName(const QString& name);

ნაგულისხმევად, objectName არის ცარიელი სტრიქონი. ამ თვისების მეშვეობით ხეში ობიექტებს შეიძლება მიენიჭოთ სახელები შემდგომი საძიებლად.

const QList &children() const;

– აბრუნებს ბავშვის ობიექტების სიას.

T findChild(const QString& name = QString()) const;

– აბრუნებს ბავშვის ობიექტს სახელად სახელი, რომელიც შეიძლება გადაიწეროს T ტიპზე, ან 0, თუ ასეთი ობიექტი არ არის ნაპოვნი. არანაირი არგუმენტი სახელიაბრუნებს ბავშვის ყველა ობიექტს. ძებნა ხორციელდება რეკურსიულად.

QList QObject::findChildren(const QString& name = QString()) const;

- აბრუნებს ყველა ბავშვის ობიექტს სახელით სახელი, რომლის ჩამოსხმაც შესაძლებელია აკრიფოთ , ან ცარიელი სია, თუ ასეთი ობიექტები არ არის ნაპოვნი. არანაირი არგუმენტი სახელიაბრუნებს ბავშვის ყველა ობიექტს. ძებნა ხორციელდება რეკურსიულად.

QList QObject::findChildren (const QRegExp& regExp) const;

- მსგავსი, მაგრამ რეგულარული გამოხატვის ძიებით regExp.

void dumpObjectTree();

– აჩვენებს გამართვის ინფორმაციას მოცემული ფესვის მქონე ობიექტების ხის შესახებ.

5.4. სიგნალები და სლოტები

მომხმარებლის გრაფიკული ინტერფეისების შექმნისას, ობიექტების ურთიერთქმედება ხშირად ხდება გამოძახების საშუალებით, ე.ი. კოდის გადაცემა შემდგომი შესრულებისთვის (ფუნქციის მაჩვენებლების, ფუნქციების და ა.შ. სახით). ასევე პოპულარული კონცეფცია ივენთიდა პროცესორები, რომელშიც დამმუშავებელი მოქმედებს როგორც მოვლენის ჩამჭრელი კონკრეტული ობიექტისთვის.

Qt წარმოგიდგენთ სიგნალების და სლოტების კონცეფციას.

სიგნალიგაგზავნილი, როდესაც გამოიძახება მისი შესაბამისი მეთოდი. პროგრამისტმა მხოლოდ უნდა მიუთითოს მეთოდის პროტოტიპი სიგნალების განყოფილებაში.

სლოტიარის მეთოდი, რომელიც შესრულებულია სიგნალის მიღებისას. სლოტები შეიძლება გამოცხადდეს საჯარო სლოტებში, დაცულ სლოტებში ან კერძო სლოტებში. ამ შემთხვევაში, დაცვის დონე გავლენას ახდენს მხოლოდ სლოტების გამოძახების უნარზე, როგორც ჩვეულებრივ მეთოდებზე, მაგრამ არა სიგნალების სლოტებთან დაკავშირების უნარზე.

სიგნალისა და სლოტის მოდელი განსხვავდება მოვლენისა და დამმუშავებლის მოდელისგან იმით, რომ სლოტს შეუძლია დაუკავშირდეს ნებისმიერი რაოდენობის სიგნალს, ხოლო სიგნალს შეუძლია დაუკავშირდეს ნებისმიერი რაოდენობის სლოტებს. სიგნალის გაგზავნისას გამოიძახება მასთან დაკავშირებული ყველა სლოტი (ზარების თანმიმდევრობა არ არის განსაზღვრული).

5.4.1. სიგნალების და სლოტების გამოცხადება, სიგნალების გაგზავნა

როგორც სლოტის ტიპიური მაგალითი, განიხილეთ ქონების მიღების მეთოდი ( მიმღები). თვისებების დაყენების მეთოდი ( სეტერი) ამ შემთხვევაში სიგნალი შეესაბამება.

ჩამონათვალი 3.1. კლასი MyClass სლოტით void setValue(int x) და სიგნალის void valueChanged(int x)
// myclass.h #include კლასი MyClass: საჯარო QObject ( Q_OBJECT საჯარო: MyClass(int x, QObject *parent = 0); int მნიშვნელობა() const; საჯარო სლოტები: void setValue (int x); სიგნალები: void valueChanged (int x); კერძო: int x_ ;

გაითვალისწინეთ Q_OBJECT მაკრო, რომელიც სიგნალს აძლევს Qt-ს, რომ გამოიყენება მეტაობიექტური სისტემა.

ჩამონათვალი 3.2. MyClass კლასის მეთოდების დანერგვა void setValue(int x) სლოტით და void valueChanged(int x) სიგნალით
// myclass.cpp #include #include "myclass.h" MyClass::MyClass (int x, QObject *parent) : QObject(parent) (setValue (x); ) int MyClass::value() const ( return x_; ) void MyClass::setValue ( int x) (თუ (x_ == x) დაბრუნდება; x_ = x; გამოსცემს მნიშვნელობა შეიცვალა (x); )

გამოსხივების საკვანძო სიტყვა პასუხისმგებელია სიგნალის გაგზავნაზე.

სიგნალისთვის მითითებულია მხოლოდ პროტოტიპი და სიგნალს არ შეუძლია დააბრუნოს მნიშვნელობა (ანუ მითითებულია void). მეტაობიექტის შემდგენელი პასუხისმგებელია იმპლემენტაციაზე, ის ასევე გარდაქმნის გაფართოებულ სინტაქსს საკვანძო სიტყვებით, სიგნალები, სლოტები, რომლებიც ასხივებენ სტანდარტულ C++ კოდს.

სინამდვილეში, საკვანძო სიტყვები შეიძლება შეიცვალოს მაკროებით Q_SIGNALS, Q_SLOTS და Q_EMIT. ეს სასარგებლოა, თუ იყენებთ მესამე მხარის ბიბლიოთეკებს, რომლებიც უკვე იყენებენ სიტყვებს signals, slots ან emit.

საკვანძო სიტყვების დამუშავება გამორთულია no_keywords დროშით. qmake პროექტის ფაილში (.pro) დაამატეთ

CONFIG += no_keywords

თქვენ შეგიძლიათ ნახოთ metaobject შემდგენელის გამოსავალი moc_slots.cpp ფაილში, რომელიც გენერირებულია slots.h-დან და კომპილირებულია დანარჩენ .cpp ფაილებთან ერთად.

5.4.2. სიგნალის დაკავშირება სლოტთან

ჩამონათვალი 3.3. void MyClass::valueChanged (int x) სიგნალის დაკავშირება void MyClass::setValue (int x) სლოტთან
// main.cpp #include #შეიცავს #include "myclass.h" int main() ( MyClass a(1); MyClass b(2); QObject::connect (&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int))); a.setValue(3);<< "a:" << a.value(); // 3 qDebug() << "b:" << b.value(); // 3 return 0; }

აქ, QObject::connect-ის გამოყენებით, a ობიექტის სიგნალი დაკავშირებულია b ობიექტის სლოტთან (მაჩვენებლები QObject-ზე გადადის). SIGNAL და SLOT მაკროები ქმნიან სიმებიანი ხელმოწერების მეთოდებს. მათი არგუმენტები უნდა შეიცავდეს პროტოტიპებს ცვლადის სახელების მითითების გარეშე, ე.ი. SIGNAL(valueCanged(int x)) არ არის სწორი ვარიანტი.

ხელმოწერები გამოიყენება ტიპის შესატყვისად: სიგნალის ხელმოწერა უნდა ემთხვეოდეს სლოტის ხელმოწერას. ამ შემთხვევაში, სლოტის ხელმოწერა შეიძლება იყოს უფრო მოკლე, თუ დამატებითი არგუმენტები იგნორირებულია.

QObject-ის დარეკვის კიდევ ერთი ვარიანტი::connect:

b.connect(&a, SIGNAL(valueCanged(int)), SLOT(setValue(int)));

ასე რომ, აქ გამოძახება MyClass::setValue-ზე გამოიწვევს MyClass::setValue-ს b-ზე.

ყურადღება მიაქციეთ ხაზს, თუ (x_ == x) დაბრუნდება; . ეს საჭიროა ციკლური კავშირების პრობლემების თავიდან ასაცილებლად. მაგალითად, შემდეგი კოდი იმუშავებს:

ჩამონათვალი 3.4. ციკლურად დამაკავშირებელი void MyClass::valueChanged (int x) სიგნალები ბათილი MyClass::setValue (int x) სლოტებით
// main.cpp #include #შეიცავს #include "slots.h" int main() ( MyClass a(0); MyClass b(1); MyClass c(2); QObject::connect (&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue (int)) QObject::connect (&b, SIGNAL(valueCanged(int)), &c, SLOT(setValue(int)));<< "a:" << a.value(); // 3 qDebug() << "b:" << b.value(); // 3 qDebug() << "c:" << c.value(); // 3 return 0; }

QObject::connect აბრუნებს true, თუ კავშირი წარმატებულია, ხოლო false სხვა შემთხვევაში - მაგალითად, როდესაც სიგნალი ან სლოტი არ არის ნაპოვნი, ან მათი ხელმოწერები შეუთავსებელია.

თუ დაამატებთ იდენტურ კავშირებს QObject::connect-ის გამოყენებით, სლოტი გამოიძახება რამდენჯერმე.

5.4.3. Გათიშვა

სიგნალის სლოტიდან გასათიშად გამოიყენეთ QObject::disconnect:

QObject:: გათიშვა (&a, SIGNAL(valueCanged(int)), &b, SLOT(setValue(int)));

თუ გამორთვა წარმატებით დასრულდა, true ბრუნდება.

თუ სიგნალის ნაცვლად (SIGNAL(...)) მიუთითებთ 0-ს, მაშინ ეს სიგნალის მიმღები (b) და სლოტი გათიშულია ნებისმიერი სიგნალისგან:

QObject:: გათიშვა (&a, 0, &b, SLOT(setValue(int)));

თუ სიგნალის მიმღების (b) და სლოტის ნაცვლად (SLOT(...)) მიუთითებთ 0-ს, მაშინ ამ სიგნალთან დაკავშირებული ყველაფერი გამორთული იქნება:

QObject:: გათიშვა (&a, SIGNAL(valueCanged(int)), 0, 0);

თუ სლოტის ნაცვლად (SLOT(...)) მიუთითებთ 0-ს, მაშინ ყველაფერი, რაც დაკავშირებულია ამ სიგნალის მიმღებთან (b) გაითიშება:

QObject:: გათიშვა (&a, SIGNAL(valueCanged(int)), &b, 0);

ჩვენ ვიღებთ შემდეგ ვარიანტებს QObject::disconnect:

// ყველაფრის გათიშვა ობიექტის მიერ გაგზავნილი სიგნალებისგან: QObject::disconnect (&a, 0, 0, 0); // იგივე, მაგრამ მეთოდის სახით: a.disconnect(); // გათიშეთ ყველაფერი SIGNAL(...) სიგნალისგან, რომელიც გაგზავნილია a ობიექტის მიერ: QObject::disconnect (&a, SIGNAL(...), 0, 0); // იგივე, მაგრამ მეთოდის სახით: ა.გათიშვა (SIGNAL(...)); // ამ მიმღების გათიშვა b: QObject::disconnect (&a, 0, &b, 0); // იგივე, ოღონდ ა მეთოდის სახით: ა.გათიშვა (&b);

როდესაც თქვენ წაშლით კავშირის ერთ-ერთ ობიექტს, Qt ავტომატურად წაშლის თავად კავშირს.

5.4.4. შეზღუდვები

მეტაობიექტის შემდგენელს აქვს მთელი რიგი შეზღუდვები, რომლებიც ასევე ეხება სიგნალებთან და სლოტებთან მუშაობას.

  1. moc არ ამუშავებს შაბლონებს ან მაკროებს, ამიტომ კლასის შაბლონებს არ შეუძლიათ სიგნალების და სლოტების განსაზღვრა, ხოლო მაკროები არ შეიძლება გამოყენებულ იქნას სიგნალებისა და სლოტების გამოცხადებისას (მათ შორის, პარამეტრების მითითებისას).

    მაკრო არ შეიძლება გამოყენებულ იქნას კოდის ნებისმიერ სფეროში, რომელიც უნდა დამუშავდეს moc-ის მიერ. კერძოდ, მათი მეშვეობით საბაზისო კლასს ვერ მიუთითებთ.

    თუმცა, წინასწარი პროცესორის ზოგიერთი მახასიათებლის გამოყენება შესაძლებელია. მარტივი პირობითი კონსტრუქტები ხელმისაწვდომია (დირექტივებით #if, #ifdef, #ifndef, #else, #elif, #endif, ასევე განსაზღვრული სპეციალური ოპერატორით). დეკლარაციების შესაქმნელად, moc-ს აქვს ბრძანების ხაზის ვარიანტი -D. qmake უტილიტა გადასცემს moc ყველა დეკლარაციას, რომელიც ჩამოთვლილია DEFINES პროექტის პარამეტრში.

    მაგალითად, moc სწორად დაამუშავებს

    #if 0 // იგნორირებული ბლოკი #endif
    ბლოკი #ifdef FOO // ... #endif

    ასევე დამუშავდება მხოლოდ იმ შემთხვევაში, თუ moc -DFOO გამოიძახება, ან თუ მის წინ არის #define FOO ხაზი.

  2. ტიპები სრულად უნდა იყოს მითითებული, რადგან QObject::connect() ადარებს მათ სიტყვასიტყვით. კერძოდ, თუ ბარის აღრიცხვა განისაზღვრება Foo კლასის შიგნით, მაშინ Foo::Bar უნდა იყოს მითითებული სიგნალის არგუმენტებში:

    კლასი Foo: საჯარო QObject ( Q_OBJECT enum Bar ( a, b, c ); სიგნალები: void somethingHappened (Foo::Bar x); );
  3. ფუნქციის მაჩვენებლების გამოყენება არ შეიძლება სიგნალისა და სლოტის პარამეტრებად. Მაგალითად,

    int (* fun)(int)

    არ არის მართებული არგუმენტი. შეგიძლიათ გამოიყენოთ typedef:

    typedef int (* fun)(int);

    როგორც წესი, უმჯობესია გამოიყენოთ მემკვიდრეობა და ვირტუალური ფუნქციები პოინტერების ნაცვლად.

  4. ჩადგმული კლასები არ შეიძლება შეიცავდეს სიგნალებს და სლოტებს.
  5. სიგნალები და სლოტები, რომლებიც აბრუნებენ მითითებებს, განიხილება ისე, თითქოს ისინი დაბრუნდნენ ბათილად.
  6. სიგნალებისა და სლოტების სექციებს შეუძლიათ მხოლოდ სიგნალების და სლოტების გამოცხადება.

5.5. Თვისებები

კლასი, რომელიც მემკვიდრეობით იღებს QObject-ს, შეიძლება შეიცავდეს თვისების დეკლარაციას Q_PROPERTY() მაკროს გამოყენებით:

Q_PROPERTY( აკრიფეთ სახელი

წაიკითხეთ getFunction

საჭირო მაკრო პარამეტრები:

  • ტიპი- ქონების ტიპი;
  • სახელი- საკუთრების სახელი;
  • getFunction- მნიშვნელობის წაკითხვის const მეთოდი; დაბრუნების ტიპი უნდა იყოს ტიპი, ტიპი *ან ტიპი&.

არჩევითი მაკრო პარამეტრები:

  • setFunction– თვისების მნიშვნელობის დაყენების მეთოდი, უნდა დააბრუნოს void და მიიღოს მხოლოდ ერთი ტიპის არგუმენტი ტიპი, ტიპი *, ან ტიპი&;
  • გადატვირთვის ფუნქცია– კონტექსტზე დამოკიდებული თვისების ნაგულისხმევი მნიშვნელობის დაყენების მეთოდს არ უნდა ჰქონდეს არგუმენტები და დააბრუნოს void;

მეთოდები შეიძლება იყოს ვირტუალური ან მემკვიდრეობით მიღებული საბაზისო კლასიდან. მრავალჯერადი მემკვიდრეობისთვის, ისინი უნდა მიეკუთვნებოდეს სიის პირველ კლასს.

არასავალდებულო ატრიბუტებისთვის DESIGNABLE, SCRIPTABLE, STORED, USER, ლოგიკური მნიშვნელობები დაშვებულია:

  • DESIGNABLE – აჩვენოს თუ არა ქონება Qt Designer-ში და მსგავს გრაფიკულ პროგრამებში. ნაგულისხმევად არის true, მაგრამ ასევე შეგიძლიათ მიუთითოთ ლოგიკური მეთოდი.
  • SCRIPTABLE – უნდა იყოს თუ არა ეს თვისება ხილული სკრიპტის ძრავისთვის. ნაგულისხმევად არის true, მაგრამ ასევე შეგიძლიათ მიუთითოთ ლოგიკური მეთოდი.
  • STORED – უნდა იყოს თუ არა საკუთრება შენახული ობიექტის მდგომარეობის შენახვისას, თუ ის გამოითვლება სხვა თვისებების მეშვეობით. ნაგულისხმევი ჭეშმარიტი.
  • USER - არის თუ არა საკუთრების რედაქტირება მომხმარებლის მიერ. როგორც წესი, კონტროლის შესაბამის კლასებს აქვთ ერთი ასეთი თვისება. ნაგულისხმევი ცრუ.

მაგალითად, QWidget აცხადებს, სხვათა შორის, შემდეგ თვისებებს:

Q_PROPERTY (QSize minimumSize READ მინიმალურიSize WRITE setMinimumSize) Q_PROPERTY (int მინიმალური სიგანე READ მინიმალური სიგანე ყალბი WRITE კომპლექტიმინიმუმსიგანე STORED false DESIGNABLE მცდარი) Q_PROPERTY (int მინიმალურისიმაღლე READ READLinimumSize)

minimalSize თვისება არის QSize ტიპის და მისი მიღება შესაძლებელია QSize minimalSize() const-ის გამოყენებით და დაყენება void setMinimumSize (const QSize&) გამოყენებით. minimalWidth და minimumHeight გამოითვლება minimalSize-დან, ამიტომ ისინი დაყენებულია STORED false-ზე.

თვისების მაგალითი USER – ტექსტის ატრიბუტი QLineEdit-ში:

Q_PROPERTY (Qstring ტექსტი READ text WRITE setText USER true)

თვისებების წაკითხვისა და ჩაწერისთვის გამოიყენება შემდეგი მეთოდები:

QVariant QObject::საკუთრება (const char * სახელი) const; bool QObject::setProperty (const char * სახელი, const QVariant& მნიშვნელობა);

property() აბრუნებს ქონების ღირებულებას ან არასწორი ვარიანტი QVariant თუ ასეთი ქონება არ არსებობს.

setProperty() აბრუნებს true-ს, თუ ობიექტს აქვს მითითებული თვისება გადაცემული მნიშვნელობასთან თავსებადი ტიპით. წინააღმდეგ შემთხვევაში, false ბრუნდება.

თუ კლასს არ აქვს მითითებული თვისება, მაშინ ის ემატება დინამიური თვისებაობიექტი. დინამიური თვისებების ჩამონათვალის მიღება შესაძლებელია გამოყენებით

QList QObject::dynamicPropertyNames() const;

მოდით შევხედოთ თვისებების გამოყენების მაგალითს. მიეცით კლასს MyClass-ს ჰქონდეს სიმებიანი თვისების ტექსტი (QString ტიპის):

ჩამონათვალი 4.1. MyClass კლასის დეკლარაცია ტექსტის თვისებით
// myclass.h #include #შეიცავს კლასი MyClass: საჯარო QObject (Q_OBJECT Q_PROPERTY(QString ტექსტი READ text WRITE setText) საჯარო: MyClass(QString ტექსტი, QObject *მშობელი = 0); QString text() const; void setText(const QString& text); პირადი: QString text_;) ;
ჩამონათვალი 4.2. MyClass კლასის მეთოდების განსაზღვრა ტექსტის თვისებით
// myclass.cpp #include #შეიცავს #include "myclass.h" MyClass::MyClass(QString ტექსტი, QObject *მშობელი) : QObject(მშობელი) (setText(ტექსტი); ) QString MyClass::text() const ( return text_; ) void MyClass::setText( const QString& ტექსტი) ( text_ = ტექსტი; )

ქონებასთან მუშაობა:

ჩამონათვალი 4.3. MyClass ობიექტის ტექსტურ თვისებებთან მუშაობა
// main.cpp #include #შეიცავს #შეიცავს #შეიცავს #შეიცავს #შეიცავს #include "myclass.h" int main() ( MyClass str("foo"); qDebug()<< "text:" << str.text(); // Через метод: str.setText("bar"); qDebug() << "text:" << str.text(); // Через setProperty() / property(): str.setProperty("text", QVariant("baz")); QVariant prop = str.property("text"); qDebug() << "text:" << prop.toString(); // Добавление динамического свойства: str.setProperty("foo", QVariant("bob")); str.setProperty("bar", QVariant("slack")); QListd_props = str.dynamicPropertyNames(); QListIterator iter(d_props); // (ჩვენ განვიხილავთ კონტეინერებსა და იტერატორებს ცალკე) ხოლო (iter.hasNext()) (const char* d_prop_name = iter.next().data(); QVariant d_prop = str.property(d_prop_name); qDebug()<< "" << d_prop_name << ":" << d_prop.toString(); } return 0; }

პროგრამამ უნდა აჩვენოს შემდეგი:

text: "foo" text: "bar" text: "baz" foo: "bob" bar: "slack"

რა თქმა უნდა, უფრო უსაფრთხო და სწრაფია გამოიძახოთ კონკრეტული კლასის მეთოდები თვისებების წაკითხვისა და ჩაწერისთვის. თვისება() და setProperty() საჭიროა, როცა კლასის შესახებ არაფერია ცნობილი, გარდა თვისებების სახელებისა და ტიპებისა.

თუ თქვენ არც კი იცით კლასის თვისებებისა და მეთოდების სია, შეგიძლიათ გამოიყენოთ მეტაობიექტი.

5.6. მუშაობა MetaObjects-თან

მეტა ობიექტი ბრუნდება მეთოდით

QObject::metaObject()

ის შეიძლება გამოყენებულ იქნას კლასის შესახებ ინფორმაციის დინამიურად მოსაძიებლად, მაგალითად, Java Reflection API-ში.

5.6.1. ძირითადი ინფორმაცია

კლასის სახელი ბრუნდება

const char * QMetaObject::className() const;

მაჩვენებელი საბაზისო კლასის მეტაობიექტს –

const QMetaObject* superClass() const;

5.6.2. მეთოდები

მხოლოდ ის მეთოდები და კონსტრუქტორებია ხელმისაწვდომი მეტაობიექტების სისტემის მეშვეობით, თუ Q_INVOKABLE მაკრო მითითებულია მათ დეკლარაციამდე:

კლასი MyClass: საჯარო QObject (Q_OBJECT საჯარო: Q_INVOKABLE MyClass(); // ხილული მეტაობიექტების სისტემისთვის Q_INVOKABLE void foo(); // ხილული void foo(); // არ ჩანს );

მეთოდებზე წვდომისთვის (სიგნალებისა და სლოტების ჩათვლით), გამოიყენეთ

int QMetaObject::methodCount() const; int QMetaObject::methodOffset() const; QMetaMethod QMetaObject::მეთოდი (int index) const;

კლასის მეთოდები და თვისებები ინდექსირებულია. მეთოდზე წვდომა ხდება ინდექსით QMetaObject::method()-ით.

მეთოდების მთლიანი რაოდენობა, მემკვიდრეობითი მეთოდების ჩათვლით, დაბრუნებულია QMetaObject::methodCount()-ით. მიკერძოებაკლასის მეთოდებს აბრუნებს QMetaObject::methodOffset() , ის გვიჩვენებს, რომელ ინდექსში იწყება ამ კლასის მეთოდები. ოფსეტი იზრდება მემკვიდრეობით და აჩვენებს საბაზისო კლასის მეთოდების რაოდენობას.

მეთოდის გავლის მაგალითი:

const QMetaObject* m_obj = obj.metaObject(); for (int i = m_obj->methodOffset(); i< m_obj->metodaCount(); i++) (qDebug()<< m_obj->მეთოდი(i).ხელმოწერა(); )

თუ ვიწყებდით ინდექსს 0, მივიღებდით მეთოდებს ყველა საბაზისო კლასიდან, მათ შორის QObject:

განადგურებული(QObject*) განადგურებული() deleteLater() _q_reregisterTimers(void*) ...

_q_-ით დაწყებული მეთოდები გამოიყენება შიდა Qt-ის მიერ და არ არის API-ს ნაწილი.

ცალკე მითითებულია კონსტრუქტორები:

QMetaMethod QMetaObject::კონსტრუქტორი (int index) const; int QMetaObject::constructorCount() const;

მაგალითად, ჩვენ ვიღებთ QObject კონსტრუქტორების სიას:

ჩამონათვალი 5. QObject კონსტრუქტორების დასკვნა მეტაობიექტური სისტემის მეშვეობით
#შეიცავს #შეიცავს #შეიცავს #შეიცავს int main() (QObject obj; const QMetaObject* m_obj = obj.metaObject(); for (int i = 0; i< m_obj->constructorCount(); i++) (qDebug()<< m_obj->კონსტრუქტორი(i).ხელმოწერა(); ) დაბრუნება 0; )

შედეგი:

QObject(QObject*) QObject()

მეთოდის, სიგნალის, სლოტის ან კონსტრუქტორის ინდექსის მიღება შესაძლებელია მისი ხელმოწერით:

int QMetaObject::indexOfConstructor (const char * კონსტრუქტორი) const; int QMetaObject::indexOfMethod (const char * მეთოდი) const; int QMetaObject::indexOfSignal (const char * signal) const; int QMetaObject::indexOfSlot (const char * slot) const;

კონსტრუქტორებისთვის მოსალოდნელია მეთოდები ან სიგნალები ნორმალიზებული ხელმოწერები. მათი მიღება შესაძლებელია სტატიკური მეთოდით

static QByteArray QMetaObject::normalizedSignature(const char * მეთოდი);

Მაგალითად,

QMetaObject::normalizedSignature ("int * foo(const QString &, QObject *)")

აბრუნებს "int*foo(QString,QObject*)".

მუშაობს იგივე გზით

static QByteArray QMetaObject::normalizedType (const char * type);

ეს არის ტექსტური გადაღება კანონიკურ ფორმაში, რომელიც გამოიყენება განსაკუთრებით სიგნალისა და სლოტის თავსებადობის შემოწმებისას.

5.6.3. Თვისებები

თქვენ შეგიძლიათ იმუშაოთ თვისებებთან ანალოგიურად.

int QMetaObject::propertyCount() const; int QMetaObject::propertyOffset() const; QMetaProperty QMetaObject::საკუთრების (int index) const;const QMetaObject* m_obj = obj.metaObject(); for (int i = m_obj->propertyOffset(); i< m_obj->>propertyCount(); i++) (qDebug()<< m_obj->თვისება(i).სახელი(); )

(თუ გადახედავთ ყველა თვისებას, მათ შორის მემკვიდრეობით, დაინახავთ მინიმუმ objectName-ს QObject-დან.)

ქონების ინდექსის მიღება შესაძლებელია მისი სახელწოდებით:

int QMetaObject::indexOfProperty (const char * name) const;

5.6.4. ტრანსფერები

აღრიცხვები რეგისტრირებულია კლასში Q_ENUMS() მაკროს გამოყენებით.

ჩამოთვლა, რომლის მნიშვნელობები შეიძლება გაერთიანდეს ბიტიური OR-ის გამოყენებით, ეწოდება დროშადა უნდა დარეგისტრირდეს Q_FLAGS() გამოყენებით.

QMetaEnum QMetaObject: :enumerator (int index) const; int QMetaObject::enumeratorCount() const; int QMetaObject::enumeratorOffset() const;
ჩამონათვალი 6.1. კლასი MyClass ტიპის აღრიცხვით და რეჟიმის დროშით
კლასი MyClass (Q_OBJECT Q_ENUMS(ტიპი) Q_FLAGS(რეჟიმი) საჯარო: enum ტიპი (A, B, C); enum რეჟიმი (წაკითხვა = 0x1, ჩაწერა = 0x2, შესრულება = 0x4); // ... );

დროშები გამოიყენება შემდეგნაირად:

int რეჟიმი = MyClass::Read | MyClass::Write; // ... if (რეჟიმი & MyClass::Write) // დაყენებულია Write დროშა? (//...)

დინამიური მუშაობა ჩამოთვლებით:

ჩამონათვალი 6.2. MyClass აღრიცხვისა და დროშების გამოტანა მეტაობიექტების სისტემის მეშვეობით
MyClassobj; const QMetaObject* m_obj = obj.metaObject(); for (int i = m_obj->enumeratorOffset() ; i< m_obj->enumeratorCount(); i++) (QMetaEnum me = m_obj->inumerator(i); if (me.isValid()) // არის სახელი ( if (me.isFlag()) // დროშა ( qDebug()<< "" << me.scope() << "::" << me.name(); } else { qDebug() << me.scope() << "::" << me.name(); } } }

შედეგი:

MyClass::Type MyClass::Mode

ჩამოთვლის ინდექსი შეიძლება მივიღოთ მისი სახელით:

int QMetaObject::indexOfEnumerator (const char * name) const;

5.6.5. CLASSINFO

Q_CLASSINFO() მაკროს გამოყენებით, შეგიძლიათ დაამატოთ სახელი-მნიშვნელობის წყვილები მეტაობიექტს. Მაგალითად,

ჩამონათვალი 7.1. კლასი MyClass CLASSINFO-თ
კლასი MyClass ( Q_OBJECT Q_CLASSINFO ("ავტორი", "ბობ დობსი") Q_CLASSINFO ("ვერსია", "0.23") // ... );

ეს წყვილები მემკვიდრეობით მიიღება და მათი მიღება შესაძლებელია მეტაობიექტიდან იმავე სქემის გამოყენებით:

QMetaClassInfo QMetaObject:: classInfo(int index) const; int QMetaObject::classInfoCount() const; int QMetaObject::classInfoOffset() const;

ზემოთ მოყვანილი მაგალითისთვის:

ჩამონათვალი 7.2. MyClass კლასის CLASSINFO-ს გამომავალი
MyClassobj; const QMetaObject* m_obj = obj.metaObject(); for (int i = m_obj->classInfoOffset(); i< m_obj->classInfoCount(); i++) (QMetaClassInfo mci = m_obj->classInfo(i); qDebug()<< mci.name() << ":" << mci.value(); }

შედეგი:

CLASSINFO ინდექსის მოძიება შესაძლებელია მისი სახელით:

int QMetaObject::indexOfClassInfo (const char * name) const;

5.6.6. კონსტრუქტორების გამოძახება და მეთოდები

არგუმენტები გადადის QGenericArgument და QGenericReturnArgument ობიექტებში. ისინი შექმნილია მაკროებით Q_ARG და Q_RETURN_ARG.

// const მითითება მნიშვნელობის გადაცემისთვის: Q_ARG (T, const T& მნიშვნელობა) // მითითება მნიშვნელობის დასაბრუნებლად: Q_RETURN_ARG (T, T& მნიშვნელობა)

გამოყენების მაგალითი:

Q_ARG(QString, "foo") Q_ARG(int, 23) Q_RETURN_ARG(QString, str)

კლასის ახალი ინსტანციის შესაქმნელად გამოიყენეთ metaobject-ის newInstance() მეთოდი, რომელიც შეიძლება გადაეცეს 10-მდე არგუმენტს.

QObject* QMetaObject::newInstance (QGenericArgument val0 = QGenericArgument(0), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 =QGenericGArgument icArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument()) const;

შეცდომის შემთხვევაში უბრუნდება 0.

მეთოდის გამოსაძახებლად გამოიყენეთ invokeMethod():

static bool QMetaObject::invokeMethod (QObject* obj, const char * წევრი, Qt::ConnectionType ტიპი, QGenericReturnArgument ret, QGenericArgument val0 = QGenericArgument(0), QGenericArgument val1 =QGeneric(QGeneric) enericArgument val3 = QGenericArgument(), QGenericArgument val4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument =QvaleneGArgument ricArgument());
  • obj- ობიექტის მაჩვენებელი;
  • წევრი- მეთოდის სახელი;
  • ტიპი- ზარის ტიპი:
    • Qt:: DirectConnection - დაუყოვნებლივ,
    • Qt::QueuedConnection – როდესაც QCoreApplication::exec() იწყებს შესრულებას,
    • Qt::AutoConnection - სინქრონული, თუ ობიექტი იმავე ძაფშია, ასინქრონული სხვა შემთხვევაში;
  • რეტ- დაბრუნების ღირებულება;

ასინქრონულად გამოძახებისას, მნიშვნელობის გამოთვლა შეუძლებელია.

გადატვირთულია invokeMethod(). თუ არ მიუთითებთ ზარის ტიპს, გამოყენებული იქნება Qt::AutoConnection. თუ არ მიუთითებთ დაბრუნების მნიშვნელობას, ის იგნორირებული იქნება.

QMetaMethod კლასი უზრუნველყოფს იგივე შესაძლებლობებს:

bool QMetaMethod::invoke (QObject* ობიექტი, Qt::ConnectionType connectionType, QGenericReturnArgument returnValue, QGenericArgument val0 = QGenericArgument(0), QGenericArgument val1 = QGenericArgument(), QGenericArgument(), QGenericArgument = QGenericArgument (), QGenericArgument val4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(), QGenericArgument (), QGenericArgument ()

ანალოგიურად, კავშირის ტიპი და/ან დაბრუნების მნიშვნელობა შეიძლება არ იყოს მითითებული.

ასინქრონული ზარი გამოიყენება, როდესაც გამოთვლას ძალიან დიდი დრო სჭირდება ისე, რომ მისი შედეგი არ არის მოსალოდნელი ზარის მომენტში. ასეთი გამოთვლები, როგორც წესი, მოთავსებულია ცალკე ძაფში, ამიტომ ნაგულისხმევად (Qt::AutoConnection) ობიექტების მეთოდებს გარე ძაფებიდან უწოდებენ ასინქრონულად.

განვიხილოთ შემდეგი კლასი:

ჩამონათვალი 8.1. MyClass კლასი კონსტრუქტორით და მეტაობიექტური სისტემისთვის ხელმისაწვდომი მეთოდებით
კლასი MyClass: საჯარო QObject ( Q_OBJECT საჯარო: Q_INVOKABLE MyClass (QString ტექსტი, QObject *მშობელი = 0); Q_INVOKABLE QString text() const; Q_INVOKABLE void setText (const QString& text); კერძო: QString text_; );

კონსტრუქტორის და მეთოდების გამოძახება:

ჩამონათვალი 8.2. MyClass კლასის კონსტრუქტორებისა და მეთოდების გამოძახება მეტაობიექტური სისტემის მეშვეობით
MyClass foo ("ფუ"); const QMetaObject* m_foo = foo.metaObject(); // ახალი ინსტანციის შექმნა: MyClass *bar = qobject_cast (m_foo->newInstance(Q_ARG(QString,"ზოლი"))); თუ (! ბარი) ( qკრიტიკული()<< "Can"t invoke constructor!"; } else { bar->setParent(&foo); qDebug()<< bar->ტექსტი(); // "bar" ) // გამოიძახეთ მეთოდი: if (!QMetaObject::invokeMethod (&foo, "setText", Q_ARG(QString,"baz"))) qCritical()<< "Can"t invoke method!"; QString val; // Вызвать метод и получить возвращенное значение: if (!QMetaObject::invokeMethod (&foo, "text", Q_RETURN_ARG(QString, val))) qCritical() << "Can"t invoke method!"; qDebug() << val; // "baz"

text() და setText() ეწოდება ამ გზით მხოლოდ როგორც მარტივი მაგალითი იმისა, თუ როგორ მუშაობს QMetaObject::invokeMethod(). როგორც უკვე იცით, ეს ორი მეთოდი უნდა იყოს დაკავშირებული საკუთრებასთან.

ასევე გაითვალისწინეთ, რომ text() აბრუნებს QString, მაგრამ არა const QString&. წინააღმდეგ შემთხვევაში, მეტაობიექტის სისტემა იფიქრებს, რომ text() აბრუნებს void.

დასკვნა

იმისათვის, რომ ეფექტურად იმუშაოს კლასებთან გაშვების დროს, Qt იყენებს სპეციალურ ობიექტის მოდელს, რომელშიც QObject-ისგან მემკვიდრეობის და metaobject შემდგენელის მიერ კოდის გენერირების გამოყენებით, ხორციელდება შემდეგი:

  • ობიექტის იერარქია;
  • dynamic_cast-ის სპეციალური ანალოგი, RTTI-სგან დამოუკიდებელი;
  • სიგნალებისა და სლოტების სისტემა;
  • ობიექტის თვისებების სისტემა;
  • დინამიური მუშაობა კლასებთან.

შემდეგ სტატიაში განვიხილავთ ტიპებს, ვარიანტებს, ცნობებს და მონაცემთა დაყოფას.

პოსტ ცხოვრების ერთი დღის შემდეგ დავიწყე კარმის გაჟონვის შემჩნევა, ამიტომ წინასწარ ბოდიშს ვიხდი სტატიაში პრეზენტაციის შესაძლო მიუღებელი სტილისთვის და სუბიექტურობისთვის.

გამარჯობა, ჰაბრაჰაბრ!

ამ ბოლო დროს არ შემიძლია ყურადღება არ მივაქციო Qt თემის პოპულარობას Hubrik-ზე, მაგრამ მიუხედავად ამისა, კომენტარებში კვლავ ვხედავ ადამიანებს, რომლებიც პირდაპირ ცრუ და გაუგებარ რაღაცეებს ​​ამბობენ. ამ პოსტით მინდოდა გამეფანტა რამდენიმე მცდარი წარმოდგენა Qt-ის შესახებ და გითხრათ რატომ თქვენ უნდა გადახვიდეთ თქვენი Java/Obj-C/.NET-დან რბილ და ფუმფულა Qt-ზე.

ჭრის ქვეშ იქნება ბევრი შთაბეჭდილება, სუბიექტურობა და ჩემი მოკრძალებული მოსაზრებები ამ საკითხზე ყველაზე მშვენიერიაპლიკაციის განვითარების ჩარჩო. თუმცა ვეცდები დავამატო საინტერესო რაღაცეები, რომ ჩემმა სტატიამ ტექნიკურად სასარგებლო მნიშვნელობა მაინც შეიძინოს. ვიმედოვნებ, რომ ეს გასართობი წასაკითხი იქნება და ისიამოვნეთ.

Აქ ჩვენ მივდივართ?

ვეშჩი No1. C++ API

საიდუმლო არ არის, რომ Qt-ს აქვს ძალიან მოსახერხებელი API და უფრო კონკრეტულად, qtbase მოდული შეიცავს კლასების საკმარის რაოდენობას ყოველდღიური ამოცანების უმეტესობისთვის ( Qt უფრო მეტია ვიდრე GUI ჩარჩო lol). მე უკვე ვისაუბრე STL კონტეინერების შესაფუთებზე სამი წლის წინ ჩემს სტატიაში - tytsk. ასევე შედის კლასები სტრინგებთან მუშაობისთვის, გამომავალი გამართვისთვის და მრავალი სხვა.

QString ხილი = "ვაშლი, ბანანი, ფორთოხალი, ბანანი"; QStringList fruitsList = fruits.split(", "); qDebug()<< fruitsList; // выведет в консоль [ "apple", "banana", "orange", "banana" ] fruitsList.removeDuplicates(); fruits = fruitsList.join(", "); qDebug() << fruits; // выведет в консоль "apple, banana, orange"
აღსანიშნავია, რომ Qt-ს ასევე აქვს მოდულები XML-თან და მონაცემთა ბაზებთან მოსახერხებელი მუშაობისთვის ( გემრიელ-გემრიელ MVC kutesh სისტემის ინტეგრაციით), OpenGL, აუდიო/ვიდეო მუშაობა (Phonon), ქსელური პროგრამირება, WebKit2. იმ ამოცანებისთვის, რომლებსაც საშუალო პროექტი აწყდება, ეს სამზარეულო საკმარისია შემთხვევების 90%-ში და პრობლემები იშვიათად ხდება მოდულებთან დაკავშირებით.

C++-ისადმი ჩემი სიყვარულის გათვალისწინებით, მე ძალიან, ძალიან კმაყოფილი ვარ იმ მხარდაჭერით, რომელიც Qt უზრუნველყოფს სხვადასხვა არა ტრივიალურ რამეებს cross-platform დონეზე. რამდენჯერმე მომიწია განსაკუთრებით გაუგებარი მომენტების გადაწყვეტა, მაგრამ ასეა.

ვეშჩი No2. Qt სწრაფი

Qt Quick არის სუპერ გლუვი მიდგომა გრაფიკული მომხმარებლის ინტერფეისის შესაქმნელად. დეკლარაციული ენის გამოყენებით, სახელწოდებით QML (გამოიცანით, სად გამოიგონეს lol), JavaScript-ის მსგავსი, შეგიძლიათ მიაღწიოთ მაღალ პროდუქტიულობას აპლიკაციებში ინტერფეისის პროტოტიპირებისას. ნებისმიერისირთულეები. და სასაცილო ის არის, რომ ასე მიდის, დიზაინერსაც კი, რომელმაც იცის JavaScript სინტაქსი, შეუძლია ინტერფეისის პროტოტიპირება. ეს ყველაფერი ცარიელი სიტყვები იქნებოდა, მე რომ არ მეჩვენებინა ფუნქციური კოდის მაგალითი (უფრო მეტი შეგიძლიათ ნახოთ Qt პროექტზე - იქ).

იმპორტი QtQuick 2.0 Rectangle ( ID: გვერდის სიგანე: 320; სიმაღლე: 480 ფერი: "ღია ნაცრისფერი" ტექსტი ( id: helloText text: "Hello world!" y: 30 anchors.horizontalCenter: page.horizontalCenter font.pointSize: 24; თამამი: true ) ბადე ( ID: colorPicker x: 4; anchors.bottom: page.bottom; anchors.bottomMargin: 4 სტრიქონი: 2; სვეტები: 3; ინტერვალი: 3 უჯრედი ( cellColor: "red"; onClicked: helloText.color = cellColor ) Cell (cellColor: "მწვანე"; onClicked: helloText.color = cellColor ) Cell (cellColor: "ლურჯი"; onClicked: helloText.color = cellColor ) Cell (cellColor: "ყვითელი"; onClicked: helloText.color. ) უჯრედი ( cellColor: "steelblue"; onClicked: helloText.color = cellColor ) Cell (cellColor: "შავი"; onClicked: helloText.color = cellColor) )

Cell ობიექტის განხორციელება უკიდურესად ტრივიალურია და ასეა განსაზღვრული

იმპორტი QtQuick 2.0 ელემენტი ( id: კონტეინერის თვისება მეტსახელი cellColor: rectangle.color სიგნალი დაწკაპუნებულია (color cellColor) სიგანე: 40; სიმაღლე: 25 Rectangle ( id: მართკუთხედის საზღვარი. ფერი: "თეთრი" წამყვანები. შევსება: მშობელი ) MouseArea (an შევსება: მშობელი onClicked: container.clicked(container.cellColor) ) )

ამ კოდში არ არის C++-ის ერთი ხაზი და ის კარგად მუშაობს. კარგია, არა? ამან თავი ჯადოქარადაც კი მაგრძნობინა - პურის საყიდლად მაღაზიაში წასვლა უფრო ადვილია, ვიდრე მსგავსი აპლიკაციის შედგენა. თუმცა კომპლექსურ აპლიკაციებში მარტო QML არ არის საკმარისი და მას C++-თან ვათავსებთ. ეს განიხილებოდა Qt Software hub-ის ბევრ სტატიაში - მაგალითად, იქ.

ვეშჩი No3. საზოგადოება

კარგი, ჩვენ მივაღწიეთ სასიამოვნო მომენტს. ჩემზე თუ ვისაუბრებთ, Qt-თან შედარებით ცოტა ვმუშაობ - მხოლოდ 5 წელია. Qt ატარებს ყოველწლიურ ღონისძიებებს - Qt Developer Days და Qt Contributors "Summit. შარშან ერთხელ ვიყავი თითოეულ მათგანზე და ძალიან მომეწონა - მომზადების დონე მაღალია, შთაბეჭდილებები კი. ასევე მომიწია კომუნიკაცია. Qt „ვეტერანები“ - ადამიანები, რომლებიც 10 წელია ესწრებიან სამიტს. წარმომიდგენია, რა მაგარია ასეთი პროექტის ზრდა საკუთარ თვალწინ და ყველა განვითარების ეპიცენტრში ყოფნა - უბრალოდ გემრიელი.

ეს ხალხი ძალიან ტოლერანტულია და კარგად ექცევა ახალმოსულებს, ჩემთვის ძალიან ადვილი და მოსახერხებელი იყო ასეთ შესანიშნავ ადამიანებთან ურთიერთობა. Qt Project-ს აქვს ფორუმები, სადაც ყველას შეუძლია მიიღოს პასუხი თავის კითხვაზე. სასაცილოა, მაგრამ ნამდვილად საზიზღარია ძალიან ცოცხალიდა იქ ნამდვილადუპასუხოს კითხვებს, რომლებიც წარმოიქმნება სწავლის პროცესში Qt.

ვეშჩი No4. ღია კოდის და კოდის მიმოხილვა

Soretz Cut ღიად არის შემუშავებული ძირითადად Digia-ს (comm. support +), KDAB, ICS და ენთუზიაზმი დეველოპერების მიერ. ყველაფერი მასპინძლობს Gitorious - Tadamts-ზე. პროექტის განვითარებაში წვლილი შეიტანოთ, თქვენ უნდა გაიაროთ მკაცრიკოდის გადამოწმება - ავტომატიზირებული (შეესაბამება კოდის სტილს, რომლის შესახებაც ადრე დავწერე - ptsss) და ადამიანური - თქვენს კოდს შეხედავენ წვერიანი მამაკაცები, რომლებიც არ გენდობიან და დაეძებენ უკანა კარებს თქვენს კოდში. ეს ყველაფერი საკმაოდ რთული პროცესია (პრობლემები Git-თან / გადასინჯებთან დაკავშირებით მიმოხილვის საბჭოში) და ალბათ ამ დღეებში დავწერ სტატიას ამის შესახებ.

სხვათა შორის, qtbase ხეზე მაქვს რამოდენიმე commits, ასე რომ თქვენ შეგიძლიათ მკითხოთ PM-ში და ვეცდები ვუპასუხო თქვენს შეკითხვებს.

ვეშჩი No5. პროექტის განვითარების დინამიკა

Qt დამუშავების პროცესშია მრავალი წლის განმავლობაში, 90-იანი წლების ბოლოდან. ამ ხნის განმავლობაში კომპანიებმა, როგორიცაა Trolltech და Nokia, უკვე ითამაშეს მისი კომერციული ვერსიით და ახლა ამას Digia აკეთებს. მაგრამ ერთი რამ ცხადია, რომ პროექტი ცოცხალი და წარმატებულია. კიდევ რამდენიმე წელი ყველა წერდა დიზაინს ვიჯეტებში (C++ კლასები, ყველა მათგანი QWidget-ზეა დაფუძნებული), მაგრამ დღეს ეს პატარა ბავშვსაც კი შეუძლია. არა მგონია, ღირს იმის თქმა, რომ ამის პარალელურად, აქტიურად ვითარდება ყველაზე ძლიერი რამ - Qt Creator, რომელიც დღეს ახარებს არა მხოლოდ Qt პროგრამისტებს!

^ მაგარი Qt Creator, რომელშიც შეგიძლიათ შექმნათ სასწაულები და ამაში ვერაფერს მიიღებთ.

სამწუხაროდ, მკაცრი რიცხვები არ მაქვს, მაგრამ ამბობენ, რომ კოდი ოპტიმიზებულია ყოველდღე, ხოლო კოდების ბაზა საგულდაგულოდ გაფართოვდა - დაემატა ახალი ფუნქციები და გამოსწორებულია ძველი შეცდომები (ეს უკვე ბევრჯერ მინახავს). ეს ყველაფერი ძალიან შესაფერისია და არ შეიძლება არ გაიხაროს.

გარდა ამისა, პლატფორმები ახლა აქტიურად ვითარდება iOS, Android, Windows Phone, ახლა შეგიძლიათ მათთვის პროგრამების შედგენა!

ქვედა ხაზი

მგონი ხვდები რომ Qt მართლა მაგარია და სტატიის წაკითხვის შემდეგ შენც ისე შემიყვარდი როგორც მე.
Გმადლობთ ყურადღებისთვის!