Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 45 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
45
Dung lượng
662,19 KB
Nội dung
6.5 Ready-made DialogsinQt 6.5.4Input Dialogs Forsimplequeries,Qtprovides various template inputdialogs,consistingofasuit- able inputwidgetand twobuttons,OKand Cancel.The relevantQInputDialog class hasonlyready-made static methods that wewillnowlook at in more detail. Frequently,you areput in thepositionofhavingtoask theusertoenter avalue.Qt distinguishesherebetween whole number valuesand floating-point values, which it provides in double precision. AcceptingIntegerInput Values Thefollowingexample(Figure 6.13) showshowthegetInteger() method of QIn- putDialog is used: bool ok; intalter=QInputDialog::getInteger(this,tr("EnterAge"), tr("Pleaseenteryearof birth"),1982, 1850,QDate::currentDate().year(),1,&ok); if (ok) { } Figure 6.13: QInputDialog::getIn- teger() with preset defaultvalue Thefirsttwoargumentsofthisare—asinother dialogs—a pointer to th eparent widgetand theheading of thedialog. Then getInteger() expectsanexplanatory text, which it displaysabovethe inputwidget. This is followed byadefault value andthenthe limitsofthe allowed inputrange.Thisexamplerestricts th eupper limit to thecurrent yeartoavoidinput that makesnosense (i.e., specifyingayear of birth in thefuture).Todothisweuse QDate, aclass for processing datedetails. ThecurrentDate()staticmethod provides thesystem time according to thecurrent date, andinturn, year()extractsthe yearfromthisand returnsitasaninteger value.Also, insteadofinserting astaticlower limit (1850), as is donehere, this can be formeddynamically(e.g., with an expressi on such as QDate::currentDate().year() -200). 179 6 Dialogs In thenext-to-l astparameter,getInteger() asks forthe amount bywhich thein- teger value should be increasedordecreased if theuserclicks on oneofthe two buttons to theright of theinput field to incrementordecrement thevalue (a so- called spin box). Since thereturn value provides no information on whether theuserhas canceled thedialogorhas made aproperdataentry,the method expectsapointer to a Boolean variable as thefinalparameter.Ifthe user cancels thedialog, getInteger() stores thevalue false in thevariable;otherwise, it is settotrue. AcceptingFloating-pointNumbersasInput Values In thesam ewayas withgetInteger(), you can also prompt theuserfor real numbers withgetDouble(). Thedialoginthe nextexampleexpectsthe pricefor agiven product.getDouble() also expectsthe pointer to theparentwidget, th edialog heading,and thedescription of theexpected inputasits first threeparameters. This is againfollowed bythedefault,minimum, andmaximum values. However,for thenext-to-lastparameter,there is adifferencebetween getInteger() andgetDouble(): Thefloating-point variant here expectsthe number of places after thedecimal point(seeFigure6.14).Weuse twooftheminthisexample, in order to specifyaprice. Figure 6.14: QInputDialog::getDouble() worksherewithonly twoplacesafter the decimalpoint. Once again, you can findout whether thedialogcompleted normallyor was in- terrupted byusinganauxilliaryvariable,the address of which is passedasthe last parameter: double getPrice(const QString&product,bool * ok) { returnQInputDialog::getDouble(this,tr("Price"), tr("Pleaseenteraprice forproduct’%1.’").arg(product), 0,0,2147483647,2,&ok); } Thevalue 2147483647 is themaximum number here that an integer can display. 180 6.5 Ready-made DialogsinQt ReadinginStrings Themostfrequentuse of QInputDialog is to allowtheusertoselectastring from several predefinedstrings.For this purposethe static method getItem()isused (Figure6.15):ThisexpectsaQStringListand displaysits contents in adrop-down widget. Figure 6.15: QInputDialog::getItem() returnsthe selected string. Again, thefirstthree parametersspecifythepointer to theparentwidget, thehead- ing, andthe user query.Thisisfollowed bythelistofstrings to be displayed.Then comesthe indexof thelistele ment that thedrop-downwidgetdisplaysatthe be- ginning.The next-to-lastparameter specifies whether theusercan add hisown entriestothe list. If this is this case, thereturn value doesnot havetomatch one of theprede fined entries. Thefinalparameter,asbefore, is theaddressofavariable that indicateswhether theuserhas terminated thedialogwithOKorCancel: QStringList languages; bool ok; languages<< "English"<< "German"<< "French"<< "Spanish"; QString language =QInputDialog::getItem(this,tr("SelectLanguage"), tr("Pleaseselectyour language"),languages, 0,false, &ok); if (ok) { } ReadinginFreeText Freelywritten texts arereadinwiththe QInputDialog method getText(). Thefol- lowingexampleintroduce sprobablythemostfrequentusage of this type of user input: en teringapassword. Thefirstthree parametersspecifythedetails of theparentwidget, dialog head- ing, anddialogtext, andare followed bythedisplayform, which is specified by 181 6 Dialogs avalue from theEchoMode enumeratorofthe QLineEditinput wid get: QLine- Edit::NormalMode displaysthe textasitisentered;QLineEdit::NoEcho prints noth- ingatall, so that anybodywatchingcannotsee howmanycharacters getText() accepts;and theQInputDialog::Passwordvalue used here causesaplaceholderto be printed for each characterentered,usuallystarsorcircularicons (Figure6.16). Figure 6.16: QInputDialog::getText() in passwordmode Since adefault value is normallynotspecifiedfor inputofapassword, wepassan emptyQStringobject as thenext-to-lastparameter. QString getPassword(const QString&resource) { QString passwd=QInputDialog::getText(this,tr("PleaseEnterPassword"), tr("Pleaseenterapasswordfor’%1’").arg(resource), QLineEdit::Password, QString(),0); } Ourfinalparameter in this exampleisa0(i.e., anullpointer)insteadofapointer to abool variable,because in thecaseofthe passworditissufficient to check thereturn value withQString::isEmpty() in ordertosee whether anythinghas been entered.Since theselasttwovaluesmatch thedefault valuesfor thefifthand sixth argumentsofQInputDialog::getText(), you can shorten themethod callinthiscase as follows: QString getPassword(const QString&resource) { QString passwd=QInputDialog::getText(this,tr("PleaseEnterPassword"), tr("Pleaseenterapasswordfor’%1’").arg(resource), QLineEdit::Password); } 6.5.5FontSelection Dialog TheQFont classisresponsible for thedescription of afonttype in Qt. Each widget hasafont()method that returnsthe currentfontasaQFontobject an dasetFont() method that sets anewfonttype.QApplicationknowsthese methods as well. It changesorreveals thestandardfonttype for newwidgets. 182 6.5 Ready-made DialogsinQt If you need to havethe user select fonttypes, you can make useofQFontDialog (Figure6.17). Figure 6.17: QFontDialog::getFont() displays thedefault font. This classoffers agetFont()staticmethod, which apartfromapointer to theparent widgetrequiresapointer to aBooleanvalue as itsfirstargument:true. bool ok; QFontfont=QFontDialog::getFont(&ok, this); If theuserhas selected afont, this value is se ttotrue. If you wanttodefine afonttype that deviates from thedefault font, you can defineanappropriate QFontobject andhanditover to getFont(). Note that theQFont object needstobe number twointhe getFont()argument list: bool ok; QFontinitial("TimesNewRoman",48); QFontfont=QFontDialog::getFont(&ok, initial, this); Here weselectTimes NewRoman. If this fontdoesnot existonthe system,Qttries to make an approximationbyfinding asimilarfontthrough theuse of heuristics. Thesecondparameter of theQFont constructorshownabovegives thefontsize, in this example48points. 6.5.6Color Selectionand Printing Dialog As wellasthe dialogs mentioneduntil now,Qtalsoprovides acolor selectionand aprintingdialog. It makesmoresense to explainthe useofthese after wehave 183 6 Dialogs introducedthe colorand paintingsystem of Qt in more detail, so thesedialogs will be introducedinChapter 10on pages275 and302. 184 7 Chapter Events, Drag and Drop,and the Clipboard From Section1.1,weknowthat allinteractiveQtprogramshave eventloops,be- cause theyworkinanevent-driven manner: GUI-basedprogramsare influenced byapplicationevents such as mousemovements. 7.1Event Loop andEvent Handler Theeventloop performs twokinds of tasks. First, it managesevents that it obtains from thewindowsystem used,suchasqueries to redrawawindowarea.Todothis it transforms them into Qt-specificevents.Events areencapsulated in classesthat arederived from theQEventbaseclass. At the same time,Qtalsogen erates it sownevents.Anexampleofthisisthe QTimerEvent, which is triggeredafter aspecific time hasexpired, setbythepro- 185 7 Events, Drag and Drop,and theClipboard grammer. Such events arealsobased on QEventand areprocessedbytheeven t loop. Each QEventhas atype.SubclassesofQEventcan contain arbitraryamountsof information;for example, QMouseEventhandles messagesabout buttons clicked andthe positionofthe mousecursor. Qt passesevents via QCoreApplication::postEvents() sp ecificallyto certainobjects. TheseobjectsmustinheritfromQObject.The method expectsthe receivingobject as thefirstparameter,followed byaQEvent. To deliver it,postEvents() passesthe eventtothe event()method of thetarget object.The task of theevent()method is to either processorignorethe incoming events,depending on therequirementsofthe classofthe receivingobject.This method is thereforealsoreferredtoasan eventhandler.Ifaneventcan notbe processedimmediatelybythereceiver,the eventisput into aqueue andscheduled for delivery.Ifanother part of theapplicationblocks theapplicationbyexecutinga syncronous long-windedope ration, 1 thequeue cannotbeprocessedbytheevent loop during that time.Usercan easilyconfusethisbehaviorwithanapplication “crashing.” Thestandardimplementationofevent()calls aseparatevirtual method for the most important eventhandlers, which alreadyused thematchingQEventsubclass as aparameter.Thisallowsustosavecode .Wewillnowtake acloserlook at how this works. 7.2HandlingEvents We willimplement awidgetthatdisplaysthe clocktimeinthe local displayformat andthe currentdate, also in theappropriate format, alternating everyten seconds (Figure7.1 on page 189).The displayitself should updateeverysecond. 7.2.1Using Specialized EventHandlers We implementthe clockinaclasscalledClockWidget, which wederivefromQ- LCDNumber, aQtclass that providesanimitation of an LCDdisplay: // clockwidget/clockwidget.h #ifndef CLOCKWIDGET_H #define CLOCKWIDGET_H #include <QLCDNumber> 1 Youcan use threads to avoidblocking.Wewill discussthisinChapter 12. 186 7.2 Handling Events class QTimerEvent; class ClockWidget:public QLCDNumber { Q_OBJECT public: ClockWidget(QWidget * parent=0); protected: void timerEvent(QTimerEvent * e); private: intupdateTimer,switchTimer; bool showClock; } ; #endif // CLOCKWIDGET_H Here weare particularlyinterested in,besides theconstruct or,the specialized event handlertimerEvent(), which willupdatethe clocktime. In theupdateTimer and switchTimermembervariableswesavenumbersthatserveasidentifiersfor the timers. TheshowClockstatusflag determineswhether theclock time (showClock= true)orthe date(showClock=false)appearsonthe wid get. Theimplementationinclockwidget.cppbeginsbyspecifyingthe formofthe dis- play.UsuallyQLCDNumber showsaframearound thedigital display.Thisbehavior, inherited from QFrame,isdisabledbytheQFrame::NoFrame framestyle.Inaddi- tion wedissuade thewidgetfromdrawingthe LCDelementswithshadowsand a border,bypassing on QLCDNumber::Flattothe widget’ssetSegmentStyle() method. // clockwidget/clockwidget.cpp #include <QtGui> #include "clockwidget.h" ClockWidget::ClockWidget(QWidget * parent) :QLCDNumber(parent),showClock(true) { setFrameShape(QFrame::NoFrame); setSegmentStyle(QLCDNumber::Flat); updateTimer=startTimer(1000); switchTimer=startTimer(10000); QTimerEvent * e=newQTimerEvent(updateTimer); QCoreApplication::postEvent(this,e); } Nowweneed twotimers. Each QObject can startatimerusing thestartTimer() method. As an argument startTimer() expectsthe number of secondsthatmust 187 7 Events, Drag and Drop,and theClipboard passbeforeittriggers aQTimerEvent, which is addressedtothe currentwidget. Each QTimerEventinturncontainsanidentification number,which is returned by theinvocationofstartTimer()thatoriginates it .Wecan usethistodistinguish between thetwotimersintimerEvent()later on. So that wedonot havetowaitfor asecondtoelapsebeforethe time appears on thewidget’sdisplay,wemanuallysend atimer eventwiththe ID of theupdate- Timer, usingthe postEvent()method of QCoreApplication. As thetargetwespecify thecurrent widget(in this case, this)aswedolater on for theevents generated by thetimersthemselves. In thetimerEvent()method wefirstcheck whether thepointer to theeventreally is valid—just to be on thesafe side.Next, if theeventcontainsthe switch Timer ID,thisonlytoggles theshowClockvariable.The act ualworkawaits in thelast conditionalstatement, which is triggeredbyan eventcontainingthe updateTimer ID. // clockwidget/clockwidget.cpp (continued) void ClockWidget::timerEvent(QTimerEvent * e) { if (!e)return; if (e->timerId() == switchTimer) showClock =!showClock; if (e->timerId() == updateTimer) { if (showClock) { QTime time =QTime::currentTime(); QString str =time.toString(Qt::LocalDate); setNumDigits(str.length()); display(str); } else { QDatedate=QDate::currentDate(); QString str =date.toString(Qt::LocalDate); setNumDigits(str.length()); display(str); } } } If thewidgetissupposed to displaythetime, then wefirstdetermine thecurrent time.InQt, theQTime classisresponsible for handlingtime. ThecurrentTime() static method of this provides thecurrent system time in aQTime object.Thistime is converted bytoString() into aQString.Qt::LocalDate instructsthe method to take into account thecountrysettings(locales)ofthe user.Finallywemustinform thedisplayhowmanyLCDdigit positions arerequired. We dedu ce this from th e string length anddisplaythestringwithdisplay(). 188 [...]... drag->start(); } } First we check whether the user is holding down the left mouse button Then we prepare the QMimeData object with the help function prepareImageDrag() (page 1 95) We obtain the path from the member variable picPath The constructor 196 7 .4 Drag and Drop retrieves the image displayed by the label from the specified path, with the help of the QLabel::setPixmap() method, as shown in the. .. window, the widget accepts the drop If you let go of the button the DropWidget accepts the graphics, as can be seen in Figure 7 .4 The program can also process drops made from file managers, thanks to its ability to interpret URLs Figure 7 .4: The DropLabel, after it has received the drop with the Qt- 4 logo 7 .5 The Clipboard The Qt QClipboard class is responsible for handling the “clipboard” provided by... description of the item for accessibility purposes Offset for your own roles that may be required in the development of your own delegates Qt: :ToolTipRole Qt: :StatusTipRole Qt: :WhatsThisRole Qt: :SizeHintRole Qt: :FontRole Qt: :TextAlignmentRole Qt: :BackgroundColorRole Qt: :TextColorRole Qt: :CheckStateRole Qt: :AccessibleTextRole Qt: :AccessibleDescriptionRole Qt: :UserRole Table 8.1: Roles in models The data()... this case has the effect that chatEdit obtains the focus before conversationView, so that the user can begin typing immediately after the program starts At the same time chatEdit obtains the focus as soon as the show() method of a ChatWindow instance is called Until now we have only learned how to specify the tab order with the help of the Qt Designer, in Chapter 3.1 .5 on page 89 If you read the C++ code... version of the index() method This function usually expects a triplet of indices (column, row, and parent) as an argument, a representation which is of no help to us here The overloaded version, on the other hand, accepts a path description encoded as a QString Figure 8 .5: Four views, one model as the source: Here the Qt QDirModel is used to display the contents of the current directory Then we specify the. .. and the Clipboard The program then looks something like what is shown in Figure 7.3 We can drag the image into various programs, such as Gimp or Paint, and see what happens to it Figure 7.3: The DragLabel with the Qt- 4 logo 7 .4. 3 The Drop Side So that we can better understand the drag-and-drop process illustrated in Figure 7.2 on page 196, we will now implement a label widget complementary to the DragLabel,... change the behavior of other QObject-based objects in this way This is of particular benefit because you do not want to reimplement a widget just to make a minor modification to its event processing A classic example of the use of event handlers is in chat dialogs, in which QTextEdit ✞ ☎ is used In contrast to the standard implementation of the class, here the ✝ Return ✆ ✞ ☎ 2 and ✝ ✆ should not start a... is the ChatWindow object itself (this) The ChatWindow will filter the keypress events of the chatEdit object and respond to them, so that we do not need to implement a specialized subclass of QTextEdit for this application Finally, we set the window title and use setTabOrder() to specify the order in which the widgets will be given focus inside the ChatWindow if the user presses the ✞ ☎ Tab key ✝ ✆ The. .. point of view, since the user can then see what he is juggling with We must ensure that the image is presented in the preview size To do this we specify a version scaled down, with scaled() KeepAspectRatio instructs the method to retain the page proportions, but not to exceed the maximum size of 100 pixels in either direction drag->start() begins the actual drag action In the pattern from Figure 7.2, the. .. Destination::dragMoveEvent() 7 .4. 2 The Drag Side We have seen how to encode data in MIME format But how do the MIME data from a widget in one part of our program manage to get to another part—or even into a completely different application? To illustrate this, Figure 7.2 shows the sequence of a typical drag-and-drop operation The source widget defines when a drag begins If the widget cannot be clicked, which is the case . to be displayed.Then comesthe indexof thelistele ment that thedrop-downwidgetdisplaysatthe be- ginning .The next-to-lastparameter specifies whether theusercan add hisown entriestothe list. If this. it,postEvents() passesthe eventtothe event()method of thetarget object .The task of theevent()method is to either processorignorethe incoming events,depending on therequirementsofthe classofthe receivingobject.This method. forproduct’%1.’").arg(product), 0,0,2 147 483 647 ,2,&ok); } Thevalue 2 147 483 647 is themaximum number here that an integer can display. 180 6 .5 Ready-made DialogsinQt ReadinginStrings Themostfrequentuse of QInputDialog