Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 74 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
74
Dung lượng
307,09 KB
Nội dung
53 Chapter 3 ✦ Laying Out Widgets in a Window Packing widgets from the end has the same effect as packing them from the start, except each widget is placed in the next available location starting at the bottom. The first button added to the bottom is the one created on lines 25 through 27, and added by the call to packEnd() on line 28. The button created and added on lines 30 through 33 takes the position directly on top of the other button packed from the bottom, and the one on lines 35 through 38 takes up a position directly above the other two at the bottom. The actions taken when a KContainerLayout widget is resized depends on how the widgets were added. Those added at the start will remain against the start edge (top or left), and those added at the end will stay against the end edge (bottom or right). To orient the packed layout horizontally, either remove the statement on line 8 (because horizontal is the default), or replace it with the following: layout->setOrientation(KContainerLayout::Horizontal); When the layout orientation is horizontal, the packStart() method inserts wid- gets on the left and the packEnd() method inserts them on the right. The result is shown in Figure 3-13. Figure 3-13: A KContainerLayout organizing widgets horizontally ISa Instead of HASa All of the previous examples in this chapter were widgets that internally created a layout manager of some sort. However, because KContainerLayout is also a wid- get, it can be extended instead of simply used. That is, the widget no longer has a layout object, it is a layout object. The following is an example of creating a widget that is capable of containing other widgets. Main 1 /* main.cpp */ 2 #include <kapp.h> 3 #include “iscontainer.h” 4 5 int main(int argc,char **argv) 6 { 7 KApplication app(argc,argv,”iscontainer”); 8 IsContainer *iscontainer = new IsContainer(); Note 4682-1 ch03.f.qc 11/20/00 15:41 Page 53 54 Part I ✦ Getting Started 9 iscontainer->show(); 10 app.setMainWidget(iscontainer); 11 return(app.exec()); 12 } This widget is treated just as any other widget would be. It is created on line 8 and set as the main-window widget on line 10. It doesn’t matter whether it has a layout component or is a layout component, as long as it is a widget. IsContainer Header 1 /* iscontainer.h */ 2 #ifndef ISCONTAINER_H 3 #define ISCONTAINER_H 4 5 #include <qwidget.h> 6 #include <kcontainer.h> 7 #include <qpushbutton.h> 8 9 class IsContainer: public KContainerLayout 10 { 11 public: 12 IsContainer(QWidget *parent=0,const char *name=0); 13 ~IsContainer(); 14 private: 15 QPushButton *One; 16 QPushButton *Two; 17 QPushButton *Three; 18 }; 19 20 #endif The main difference between this class definition and the ones in the previous examples is that, on line 8, IsContainer inherits from KContainerLayout instead of inheriting directly from QWidget. The IsContainer class is still a widget because KContainerLayout inherits from QWidget. IsContainer 1 /* iscontainer.cpp */ 2 #include “iscontainer.h” 3 4 IsContainer::IsContainer(QWidget *parent,const char *name) 5 : KContainerLayout(parent,name) 6 { 7 setOrientation(KContainerLayout::Vertical); 8 9 One = new QPushButton(this); 10 One->setText(“BUTTON ONE”); 11 One->setMinimumSize(One->sizeHint()); 12 packStart(One); 4682-1 ch03.f.qc 11/20/00 15:41 Page 54 55 Chapter 3 ✦ Laying Out Widgets in a Window 13 14 Two = new QPushButton(this); 15 Two->setText(“BUTTON TWO”); 16 Two->setMinimumSize(Two->sizeHint()); 17 packStart(Two); 18 19 Three = new QPushButton(this); 20 Three->setText(“BUTTON THREE”); 21 Three->setMinimumSize(Three->sizeHint()); 22 packStart(Three); 23 24 resize(10,10); 25 } 26 IsContainer::~IsContainer() { } The super classes (including the QWidget class) are initialized by the code on line 5. Line 7 sets the orientation to vertical. Lines 9 through 22 create and add three but- tons to the container by calling packStart(). The resulting display is shown in Figure 3-14. Figure 3-14: A widget container layout with three child widgets Widgets Inside Widgets (Horizontal) Because KContainerLayout is a widget, and has the ability to contain other wid- gets, it can contain other KContainerLayout widgets. The following example is a collection of horizontal KContainerLayout widgets contained inside a vertical KContainerLayout widget. This example also displays the effect of using different combinations of options when creating the container and adding child widgets to it. Main 1 /* main.cpp */ 2 #include <kapp.h> 3 #include “horizlayout.h” 4 5 int main(int argc,char **argv) 6 { 7 KApplication app(argc,argv,”horizlayout”); 8 HorizLayout *horizlayout = new HorizLayout(); 9 horizlayout->show(); 10 app.setMainWidget(horizlayout); 11 return(app.exec()); 12 } 4682-1 ch03.f.qc 11/20/00 15:41 Page 55 56 Part I ✦ Getting Started HorizLayout Header 1 /* horizlayout.h */ 2 #ifndef HORIZLAYOUT_H 3 #define HORIZLAYOUT_H 4 5 #include <qwidget.h> 6 #include <kcontainer.h> 7 #include <qpushbutton.h> 8 9 class HorizLayout: public QWidget 10 { 11 public: 12 HorizLayout(QWidget *parent=0,const char *name=0); 13 ~HorizLayout(); 14 private: 15 void add(KContainerLayout *layout,int count, 16 bool homogeneous,bool expand,bool fill); 17 }; 18 19 #endif HorizLayout 1 /* horizlayout.cpp */ 2 #include “horizlayout.h” 3 #include <qlabel.h> 4 5 HorizLayout::HorizLayout(QWidget *parent,const char *name) 6 : QWidget(parent,name) 7 { 8 KContainerLayout *layout = new KContainerLayout(this, 9 NULL, 10 KContainerLayout::Vertical, 11 FALSE, 12 5, 13 0, 14 TRUE); 15 16 int count = 1; 17 add(layout,count++,FALSE,TRUE,TRUE); 18 add(layout,count++,TRUE,TRUE,TRUE); 19 add(layout,count++,FALSE,FALSE,TRUE); 20 add(layout,count++,TRUE,FALSE,TRUE); 21 add(layout,count++,FALSE,TRUE,FALSE); 22 add(layout,count++,TRUE,TRUE,FALSE); 23 add(layout,count++,FALSE,FALSE,FALSE); 24 add(layout,count++,TRUE,FALSE,FALSE); 25 26 layout->sizeToFit(); 27 } 4682-1 ch03.f.qc 11/20/00 15:41 Page 56 57 Chapter 3 ✦ Laying Out Widgets in a Window 28 void HorizLayout::add(KContainerLayout *outer,int count, 29 bool homogeneous,bool expand,bool fill) 30 { 31 QPushButton *button; 32 33 QString str(tr(“%1. “).arg(count)); 34 if(homogeneous) 35 str.append(“Homogeneous”); 36 else 37 str.append(“Non-homogeneous”); 38 if(expand) 39 str.append(“, expand”); 40 else 41 str.append(“, no-expand”); 42 if(fill) 43 str.append(“, fill”); 44 else 45 str.append(“, no-fill”); 46 47 QLabel *label = new QLabel(str,outer); 48 label->setMinimumSize(label->sizeHint()); 49 outer->packStart(label); 50 51 KContainerLayout *inner = new KContainerLayout(outer, 52 NULL, 53 KContainerLayout::Horizontal, 54 homogeneous, 55 5, 56 0, 57 TRUE); 58 59 button = new QPushButton(inner); 60 button->setText(“ONE”); 61 button->setMinimumSize(button->sizeHint()); 62 inner->packStart(button,expand,fill); 63 64 button = new QPushButton(inner); 65 button->setText(“BUTTON TWO”); 66 button->setMinimumSize(button->sizeHint()); 67 inner->packStart(button,expand,fill); 68 69 button = new QPushButton(inner); 70 button->setText(“THREE”); 71 button->setMinimumSize(button->sizeHint()); 72 inner->packStart(button,expand,fill); 73 74 inner->sizeToFit(); 75 outer->packStart(inner); 76 } 77 HorizLayout::~HorizLayout() { } 4682-1 ch03.f.qc 11/20/00 15:41 Page 57 58 Part I ✦ Getting Started The vertically oriented KContainerLayout that acts as the container for the top- level window is created on line 8. Each of the calls to add(), on lines 17 through 24, adds a new label and a horizontal KContainerLayout widget to the top-level KContainerLayout. To set positioning for the widgets within the horizontal con- tainer, there are three basic mode toggles, so the add() method is called once for each of the eight possible combinations. The first argument to add() is the address of the container widget, the second is a number to be assigned to the displayed data, and the other three arguments are the mode switch settings that will control widget placement. The result is shown in Figure 3-15. Figure 3-15: The eight KContainerLayout horizontal configuration settings The method add(), starting on line 28, creates a descriptive label and a horizontal KContainerLayout widget, and then adds them to the KContainerLayout widget passed in as the first argument. The method begins by creating a QString that describes the option settings. The string construction begins on line 33 with the conversion of the number into a string. Lines 34 through 45 test each of the three Boolean settings and append text accordingly. The string is used to construct a QLabel on line 47; and on line 49, the label is packed into the top of the KContainer Layout of the main window. The horizontal container is created on lines 51 through 57. Note that the KContainerLayout that is going to contain it is named as the parent widget on line 51. It is not assigned a name, but is set to horizontal orientation on line 53. Whether or not the sizing and placement is to be homogeneous is set on line 54 according to the argument passed in to this method. Lines 59 through 72 create three buttons 4682-1 ch03.f.qc 11/20/00 15:41 Page 58 59 Chapter 3 ✦ Laying Out Widgets in a Window and add them to the horizontal KContainerLayout widget. The other two configu- ration settings, expand and fill, are used on the calls to packStart(), which adds the buttons to the container. Each of the buttons is created with its container as its parent, but still must be packed into the container to be displayed. For example, the first button is created on line 59 using the inner KContainerLayout widget as its parent. This is neces- sary because messages propagate up and down the widget hierarchy, and there must be communications between the button and its container. Then, on line 67, the button is packed into the start of the container, thus being assigned its specific position within the container. With these two relationships, the container can read size information from the button, calculate the exact size and position the button is to fill, and write any necessary information back to the button. The three settings— homogeneous, expand, and fill — all deal with the size and position of the widgets in a container, and they all have slightly different meanings. In Figure 3-15, you could see the effects of each. Table 3-1 briefly describes the effects of each setting. Table 3-1 The Widget Positional Options in a KContainerLayout Option Description homogeneous If TRUE, all the widgets in the container will be assigned the same amount of space. This assignment is made regardless of the actual size of the widget. If FALSE, each widget will determine its own space requirements, and the widgets could possibly be different sizes. Whether TRUE or FALSE, expansion and contraction of the window will expand and contract the widgets according to their allocated space. expand If TRUE, the widget should make use of the entire space allocated to it by the container. fill If expand is TRUE, setting fill to TRUE will instruct the widget to size itself to fill the entire space allocated to it by the container. Widgets Inside Widgets (Vertical) This example is the same as the previous one, except for the orientation. This pro- gram organizes button widgets in columns. The top-level widget is a horizontally oriented KContainerLayout widget that has been filled with a collection of verti- cally oriented KContainerLayout widgets. 4682-1 ch03.f.qc 11/20/00 15:41 Page 59 60 Part I ✦ Getting Started Each column in this example is configured the same way as its corresponding row in the previous example. As shown in Figure 3-16, each vertical KContainerLayout is numbered. You can use these numbers to compare the appearance of the vertical layout shown in Figure 3-16 to its horizontal counterpart, shown in Figure 3-15. Figure 3-16: The eight KContainerLayout vertical configuration settings Main 1 /* main.cpp */ 2 #include <kapp.h> 3 #include “vertlayout.h” 4 5 int main(int argc,char **argv) 6 { 7 KApplication app(argc,argv,”vertlayout”); 8 VertLayout *vertlayout = new VertLayout(); 9 vertlayout->show(); 10 app.setMainWidget(vertlayout); 11 return(app.exec()); 12 } VertLayout Header 1 /* vertlayout.h */ 2 #ifndef VERTLAYOUT_H 3 #define VERTLAYOUT_H 4 5 #include <qwidget.h> 6 #include <kcontainer.h> 7 #include <qpushbutton.h> 8 9 class VertLayout: public QWidget 10 { 11 public: 12 VertLayout(QWidget *parent=0,const char *name=0); 13 ~VertLayout(); 14 private: 4682-1 ch03.f.qc 11/20/00 15:41 Page 60 61 Chapter 3 ✦ Laying Out Widgets in a Window 15 void add(KContainerLayout *layout,int count, 16 bool homogeneous,bool expand,bool fill); 17 }; 18 19 #endif VertLayout 1 /* vertlayout.cpp */ 2 #include “vertlayout.h” 3 #include <qlabel.h> 4 5 VertLayout::VertLayout(QWidget *parent,const char *name) 6 : QWidget(parent,name) 7 { 8 KContainerLayout *layout = new KContainerLayout(this, 9 NULL, 10 KContainerLayout::Horizontal, 11 FALSE, 12 3, 13 0, 14 TRUE); 15 16 int count = 1; 17 add(layout,count++,FALSE,TRUE,TRUE); 18 add(layout,count++,TRUE,TRUE,TRUE); 19 add(layout,count++,FALSE,FALSE,TRUE); 20 add(layout,count++,TRUE,FALSE,TRUE); 21 add(layout,count++,FALSE,TRUE,FALSE); 22 add(layout,count++,TRUE,TRUE,FALSE); 23 add(layout,count++,FALSE,FALSE,FALSE); 24 add(layout,count++,TRUE,FALSE,FALSE); 25 26 layout->sizeToFit(); 27 } 28 void VertLayout::add(KContainerLayout *outer,int count, 29 bool homogeneous,bool expand,bool fill) 30 { 31 QPushButton *button; 32 33 KContainerLayout *inner = new KContainerLayout(outer, 34 NULL, 35 KContainerLayout::Vertical, 36 homogeneous, 37 5, 38 0, 39 TRUE); 40 41 QString str(tr(“%1. “).arg(count)); 42 QLabel *label = new QLabel(str,outer); 43 label->setMinimumSize(label->sizeHint()); 4682-1 ch03.f.qc 11/20/00 15:41 Page 61 62 Part I ✦ Getting Started 44 label->setMaximumSize(label->sizeHint()); 45 outer->packStart(label,FALSE,FALSE); 46 47 button = new QPushButton(inner); 48 button->setText(“Btn 1”); 49 button->setMinimumSize(button->sizeHint()); 50 inner->packStart(button,expand,fill); 51 52 button = new QPushButton(inner); 53 button->setText(“Btn\n2”); 54 button->setMinimumSize(button->sizeHint()); 55 inner->packStart(button,expand,fill); 56 57 button = new QPushButton(inner); 58 button->setText(“Btn 3”); 59 button->setMinimumSize(button->sizeHint()); 60 inner->packStart(button,expand,fill); 61 62 inner->sizeToFit(); 63 outer->packStart(inner,TRUE); 64 } 65 VertLayout::~VertLayout() { } The VertLayout class is very much like the HorizLayout class shown in the previ- ous example. The only real difference is the orientation. In this example, the top- level window is a horizontal KContainerLayout object filled with labels and vertical KContainerLayout objects. The descriptive labels were reduced to numbers to save space. The KContainerLayout widget used as the top-level widget is created, with hori- zontal orientation, on line 8. Lines 16 through 24 repeatedly call the add() method to create the set of labeled vertical KContainerLayout widgets and add them to the top-level KContainerLayout widget. The add() method starting on line 28 creates a label and a vertically oriented KContainerLayout widget and adds them (label first) to the KContainerLayout widget passed in as the first argument. The second button, created on lines 52 through 55, contains a newline character in its text so the text will be displayed as two lines — this makes the second button larger than the others to demonstrate how the shifting and sizing works with non-uniform widgets. 4682-1 ch03.f.qc 11/20/00 15:41 Page 62 [...]... reject() to set the internal flag to FALSE and to close the dialog’s window Makefile 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 INCL= -I$(QTDIR)/include -I$(KDEDIR)/include CFLAGS= -O2 -fno-strength-reduce LFLAGS= -L$(QTDIR)/lib -L$(KDEDIR)/lib -L/usr/X11R6/lib LIBS= -lkdecore -lkdeui -lqt -lX11 -lXext -ldl CC=g++ recaption: recaption.o mainwidget.o moc_mainwidget.o... MainWidget 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 /* mainwidget.cpp */ #include “mainwidget.h” #include “entername.h” #include MainWidget::MainWidget(QWidget *parent,const char *name) : QWidget(parent,name) { setMinimumSize (20 0,80); setMaximumSize (20 0,80); QPushButton *button = new QPushButton(“Update Name”,this); button->setGeometry(50 ,20 ,100,40);... Q_OBJECT macro on line 12 must be present in order for there to be a slot, as declared on lines 12 and 13 The slot method popupDialog() will be called whenever the button is clicked Note The concept of signals and slots was introduced in Chapter 2, and is covered in detail later in this chapter TopLevel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 /* toplevel.cpp... 79 46 82- 1 ch04.f.qc 80 11/13/00 14:10 Page 80 Part I ✦ Getting Started The header file and the mainline of the program are identical to those in the previous example The only difference between the programs is the set of arguments passed to the constructor of KDialogBase MainWidget 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43... of the dialog Lines 19 through 22 specify the names of the slots The okButtonSlot(), applyButtonSlot(), and cancelButtonSlot() methods are local slots to receive button clicks The signal captionString() on line 24 is the signal that will be emitted whenever the user issues a new caption string EnterName 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 /* entername.cpp */ #include... MainWidget 1 2 3 4 5 6 7 8 9 10 11 12 /* mainwidget.cpp */ #include “mainwidget.h” #include #include MainWidget::MainWidget(QWidget *parent,const char *name) : QWidget(parent,name) { setMinimumSize (20 0,80); setMaximumSize (20 0,80); QPushButton *button = 46 82- 1 ch04.f.qc 11/13/00 14:10 Page 79 Chapter 4 ✦ Displaying a Pop-Up Dialog 13 14 15 16 17 18 19 20 21 22 23 24 25 new... new QLabel(str,this); label->setAlignment(Qt::AlignCenter); label->setGeometry(50 ,20 ,100,40); 46 82- 1 ch04.f.qc 11/13/00 14:10 Page 85 Chapter 4 ✦ Displaying a Pop-Up Dialog 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 button = new QPushButton(“Modify”,this); button->setGeometry(50,80,100,40); connect(button,SIGNAL(clicked()), this,SLOT(popupKdb())); resize(10,10); } void MainWidget::popupKdb()... = new QLabel(“width:”,this); wLabel->setAlignment(Qt::AlignCenter); hLayout->addWidget(wLabel); width = new QLineEdit(mainWidget); 46 82- 1 ch04.f.qc 11/13/00 14:10 Page 87 Chapter 4 ✦ Displaying a Pop-Up Dialog 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 width->setMaximumWidth(50); hLayout->addWidget(width); QLabel *hLabel = new QLabel(“height:”,this); hLabel->setAlignment(Qt::AlignCenter);... adjust either dimension to a larger size Modify Header 1 2 3 4 5 6 7 8 9 10 /* modify.h */ #ifndef MODIFY_H #define MODIFY_H #include #include #include class Modify: public KDialogBase { 85 46 82- 1 ch04.f.qc 86 11/13/00 14:10 Page 86 Part I ✦ Getting Started 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Q_OBJECT public: Modify(QWidget *parent=0,const char *name=0);... EnterName(QWidget *parent=0,const char *name=0); private slots: void okButtonSlot(); void applyButtonSlot(); void cancelButtonSlot(); 71 46 82- 1 ch04.f.qc 72 11/13/00 14:10 Page 72 Part I ✦ Getting Started 23 signals: 24 void captionString(QString &); 25 }; 26 27 #endif This header file defines the class of the pop-up dialog used to prompt for a new caption string It has slots to receive button clicks, . QDialog(0,”popup”,FALSE); 20 dialog->setCaption(“A QDialog Window”); 21 dialog->setMinimumSize (20 0,80); 22 dialog->setMaximumSize (20 0,80); 23 24 QPushButton *button = 25 new QPushButton(“Pop Down”,dialog); 26 . Three = new QPushButton(this); 20 Three->setText(“BUTTON THREE”); 21 Three->setMinimumSize(Three->sizeHint()); 22 packStart(Three); 23 24 resize(10,10); 25 } 26 IsContainer::~IsContainer(). private slots: 20 void okButtonSlot(); 21 void applyButtonSlot(); 22 void cancelButtonSlot(); Note 46 82- 1 ch04.f.qc 11/13/00 14:10 Page 71 72 Part I ✦ Getting Started 23 signals: 24 void captionString(QString