加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 QT4中文手册

QT4中文手册

QT4中文手册

my5xiang
2009-04-04 0人阅读 举报 0 0 暂无简介

简介:本文档为《QT4中文手册pdf》,可适用于IT/计算机领域

从HelloHelloHelloHelloQtQtQtQt开始差不多所有的程序教材都从Hello开始下面就是这个程序的qt版本。#include<QApplication>#include<QLabel>intmain(intargc,char*argv){QApplicationapp(argc,argv)QLabel*label=newQLabel("HelloQt!")label>show()returnappexec()}按行解析以上行代码第一二行:是代码中需要使用的类的头文件。在Qt中可以写成<QApplication>的格式当然也可写成“QApplicationh”。第三行:是main函数的标准写法第五行:创建一个QApplication对象管理应用程序的资源。第六行:QLabel对象QLabel是一个Qt提供的小控件显示一行文本。第七行:显示QLabel。第八行:QApplicationexec()让程序进入消息循环。等待可能的菜单工具条鼠标等的输入进行响应。将以上代码放到名为hellocpp中保存编译过程如下:qmakeprojectqmake命令创建hellopro是平台无关的工程文件。在hellopro所在目录下运行make(unix)或者nmake(windows)。第行代码还可以如下替换:QLabel*label=newQLabel("<h><i>Hello<i>""<fontcolor=red>Qt!<font><h>")这里面包含了html文本显示的字体颜色会改变。实际程序中下面两行是比不可少的。QApplicationapp(argc,argv)returnappexec()连接信号和响应函数连接信号和响应函数这个例子用来说明怎么响应信号和hello程序的源代码相似原来的Label用一个按钮代替点击时退出程序。源程序如下:#include<QApplication>#include<QPushButton>intmain(intargc,char*argv){QApplicationapp(argc,argv)QPushButton*button=newQPushButton("Quit")QObject::connect(button,SIGNAL(clicked()),app,SLOT(quit()))button>show()returnappexec()}当有所动作或者状态改变qt的控件会发出消息(signal)例如当点击按钮时按钮会发送clicked()消息这个消息可以连接到一个函数上(这个函数在这里成为slot)。这样当一个消息发送时slot函数可以自动执行。在这个例子中我们连接了按钮的clicked信号和QApplication的quit函数语法如第七八行所示。编译以上程序将以上代码放在quitcpp文件中保存。依次运行qmakeprojectqmakequitpromake(unixorlinux)ornmake(windows)然后运行程序点击Quit按钮程序将会中止。控件的几何排列-LayingLayingLayingLayingOutOutOutOutWidgetsWidgetsWidgetsWidgets在这个小节中我们说明在一个窗口中如何排列多个控件。学习利用signal和slot的方法使控件同步。程序要求用户通过spinbox或者slider输入年龄。程序中使用了三个控件:QSpinBoxQSlider和QWidget。QWidget是这个程序的主窗口。QSpinBox和QSlider被放在QWidget中他们是QWidget的children。反过来我们也可以称QWidget是QSpinBox和QSlider的parent。QWidget没有parent因为它是程序的顶层窗口。在QWidget及其子类的构造函数中都有一个QWidget*参数用来指定它们的父控件。源代码如下:#include<QApplication>#include<QHBoxLayout>#include<QSlider>#include<QSpinBox>intmain(intargc,char*argv){QApplicationapp(argc,argv)QWidget*window=newQWidgetwindow>setWindowTitle("EnterYourAge")QSpinBox*spinBox=newQSpinBoxQSlider*slider=newQSlider(Qt::Horizontal)spinBox>setRange(,)slider>setRange(,)QObject::connect(spinBox,SIGNAL(valueChanged(int)),slider,SLOT(setValue(int)))QObject::connect(slider,SIGNAL(valueChanged(int)),spinBox,SLOT(setValue(int)))spinBox>setValue()QHBoxLayout*layout=newQHBoxLayoutlayout>addWidget(spinBox)layout>addWidget(slider)window>setLayout(layout)window>show()returnappexec()}第行建立程序的主窗口控件设置标题。第到行创建主窗口的children并设置允许值的范围。第到第行是spinBox和slider的连接以使之同步显示同一个年龄值。不管那个控件的值发生变化都会发出valueChanged(int)信号另一个控件的setValue(int)函数就会为这个控件设置一个新值。第行将spinBox的值设置为这时spinBox发出valueChanged(int)信号int的参数值为这个参数传递给slider的setValue(int)函数将slider的值也设置为。同理slider也会发出valueChanged(int)信号触发spinBox的setValue(int)函数。这个时候因为spinBox的当前值就是所以spinBox不会发送任何信号不会引起死循环。在第至行我们使用了一个布局管理器排列spinBox和slider控件。布局管理器能够根据需要确定控件的大小和位置。Qt有三个主要的布局管理器:QHBoxLayout:水平排列控件。QVBoxLayout:垂直排列控件。QGridLayout:按矩阵方式排列控件第行QWidget::setLayout()把这个布局管理器放在window上。这个语句将spinBox和slider的“父”设为window即布局管理器所在的控件。如果一个控件由布局管理器确定它的大小和位置那个创建它的时候就不必指定一个明确的“父”控件。现在虽然我们还没有看见spinBox和slider控件的大小和位置它们已经水平排列好了。QHBoxLayout能合理安排它们。我们不用在程序中考虑控件在屏幕上的大小和位置这些头疼的事情了交给布局管理器就万事大吉。在Qt中建立用户界面就是这样简单灵活。程序员的任务就是实例化所需要的控件按照需要设置它们的属性把它们放到布局管理器中。界面中要完成任务由Qt的signal和slot完成。第二章创建对话框(CreatingCreatingCreatingCreatingDialogsDialogsDialogsDialogs)在这章介绍如何创建Qt的对话框。对话框是程序和用户交互的桥梁提供了程序和用户之间对话的一种方式。很多程序都是由一个主窗口在这个主窗口中包含一个菜单条多个工具条和足够多的对话框。也有些程序本身就是一个对话框直接相应用户的输入请求。本章中我们首先会用代码的方式创建我们的第一个对话框然后用QtDesigner工具创建对话框。QtDesigner是一个可视化的工具用它可以更快的创建修改对话框。派生对话框类(SubclassingSubclassingSubclassingSubclassingQDialogQDialogQDialogQDialog)第一个例子是一个用C实现的查找对话框。我们把这个对话框实现为一个类这样它就是一个独立的控件并有自己的信号(signal)和slot函数类的源代码分别放在finddialogh和finddialogcpp中。首先看finddialogh的代码#ifndefFINDDIALOGH#defineFINDDIALOGH#include<QDialog>classQCheckBoxclassQLabelclassQLineEditclassQPushButtonclassFindDialog:publicQDialog{QOBJECTpublic:FindDialog(QWidget*parent=)signals:voidfindNext(constQStringstr,Qt::CaseSensitivitycs)voidfindPrevious(constQStringstr,Qt::CaseSensitivitycs)privateslots:voidfindClicked()voidenableFindButton(constQStringtext)private:QLabel*labelQLineEdit*lineEditQCheckBox*caseCheckBoxQCheckBox*backwardCheckBoxQPushButton*findButtonQPushButton*closeButton}#endif一共行第行是为了避免头文件被多次包含。第行包含QDialog头文件这个类从QDialog继承QDialog从QWidget继承。第至行是用到的Qt中类的前向声明。通过前向声明编译器就知道这个类已经存在而不用写出包含的头文件。这个问题稍后还要讲。第至行是类FindDialog的定义。第行QOBJECT是一个宏定义如果类里面用到了signal或者slots就要声明这个宏。第行FindDialog(QWidget*parent=)构造函数是Qt控件类的标准格式默认的父参数为说明没有父控件。第行signal声明了这个对话框发出的两个信号如果选择向前查找那么对话框就发出findPrevious()信号否则发出findNext()信号。signal也是一个宏在编译之前C预处理把它变成标准的c代码。Qt::CaseSensitivity是一个枚举类型有Qt::CaseSensitive和Qt::CaseInsensitive两个值。在类的私有部分声明有两个slot函数。为了实现这两个函数需要用到对话框的其他控件的信息所以保存了一些控件的指针。slot关键字和signal一样也是一个宏。对于私有成员变量我们只是使用了它们的指针没有对它们进行存取操作编译器不需要知道它们的详细定义所以只使用了这些类的前向声明。当然也可以使用<QCheckBox><QLabel>等但是使用前向声明会让编译速度更快一些。下面看一下finddialogcpp源文件代码:文件头和构造函数部分#include<QtGui>#include"finddialogh"FindDialog::FindDialog(QWidget*parent):QDialog(parent){label=newQLabel(tr("Findwhat:"))lineEdit=newQLineEditlabel>setBuddy(lineEdit)caseCheckBox=newQCheckBox(tr("Matchcase"))backwardCheckBox=newQCheckBox(tr("Searchbackward"))findButton=newQPushButton(tr("Find"))findButton>setDefault(true)findButton>setEnabled(false)closeButton=newQPushButton(tr("Close"))connect(lineEdit,SIGNAL(textChanged(constQString)),this,SLOT(enableFindButton(constQString)))connect(findButton,SIGNAL(clicked()),this,SLOT(findClicked()))connect(closeButton,SIGNAL(clicked()),this,SLOT(close()))QHBoxLayout*topLeftLayout=newQHBoxLayouttopLeftLayout>addWidget(label)topLeftLayout>addWidget(lineEdit)QVBoxLayout*leftLayout=newQVBoxLayoutleftLayout>addLayout(topLeftLayout)leftLayout>addWidget(caseCheckBox)leftLayout>addWidget(backwardCheckBox)QVBoxLayout*rightLayout=newQVBoxLayoutrightLayout>addWidget(findButton)rightLayout>addWidget(closeButton)rightLayout>addStretch()QHBoxLayout*mainLayout=newQHBoxLayoutmainLayout>addLayout(leftLayout)mainLayout>addLayout(rightLayout)setLayout(mainLayout)setWindowTitle(tr("Find"))setFixedHeight(sizeHint()height())}到这里FindDialog的构造函数就完成了。在传见控件和布局时我们使用了new一般情况下我们还需要写析构函数delete这些控件。但是在Qt中这是不需要的当父控件销毁时Qt自动删除它所有的子控件和布局。下面是FindDialog类的两个slot函数:voidFindDialog::findClicked(){QStringtext=lineEdit>text()Qt::CaseSensitivitycs=caseCheckBox>isChecked()Qt::CaseSensitive:Qt::CaseInsensitiveif(backwardCheckBox>isChecked()){emitfindPrevious(text,cs)}else{emitfindNext(text,cs)}}voidFindDialog::enableFindButton(constQStringtext){findButton>setEnabled(!textisEmpty())}当用户点击findButton按钮findClicked()就会调用根据backwardCheckBox状态他发出findPrevious()或者findNext()信号。emit也是一个Qt的宏。当用户改变lineEdit中的文本enableFindButton()slot函数就会调用。如果输入了文本那么让findButton有效否则就无效。最后创建maincpp测试FindDialog对话框。#include<QApplication>#include"finddialogh"intmain(intargc,char*argv){QApplicationapp(argc,argv)FindDialog*dialog=newFindDialogdialog>show()returnappexec()}运行qmake编译程序。由于在FindDialog中包含了QOBJECT宏由qmake生成的makefile会保换特殊的规则运行moc(Qt的原对象编译器)。为了确保moc正确工作类定义必须放在头文件而不能放在实现文件中。由moc生成的代码中包含这个头文件并加入它自己实现的C代码。使用了QOBJECT宏的类必须运行moc。如果使用qmake那么makefile里自动包含相关的规则。如果忘记了运行moc就会发生连接错误。不同的编译器给出的提示信息不同有的会非常晦涩。GCC给出的错误信息如下:finddialogo:Infunction'FindDialog::tr(charconst*,charconst*)':usrlibqtsrccorelibglobalqglobalh::undefinedreferenceto'FindDialog::staticMetaObject'VisualC中的输出是这样:finddialogobj:errorLNK:unresolvedexternalsymbol"public:~virtualintthiscallMyClass::qtmetacall(enumQMetaObject::Call,int,void**)"这时需要重新运行qmake更新makefile然后编译程序。运行程序如果看到了快键测试ALTW,ALTC,ALTB,ALTF引发相应的处理程序。使用TAB键在将焦点改变到不同的控件上。默认的TAB键是控件创建的顺序。QWidget::setTabOrder()可以改变这个顺序。提供合适的tab顺序和快键可以让用户不用鼠标也可以运行程序通过键盘可以快速控制程序。深入信号和槽(SignalsSignalsSignalsSignalsandandandandSlotsSlotsSlotsSlotsininininDepthDepthDepthDepth)信号和槽是Qt编程的一个重要部分。这个机制可以在对象之间彼此并不了解的情况下将它们的行为联系起来。在前几个例程中我们已经连接了信号和槽声明了控件自己的信号和槽并实现了槽函数发送了信号。现在来更深入了解这个机制。槽和普通的c成员函数很像。它们可以是虚函数(virtual)也可被重载(overload)可以是公有的(public)保护的(protective)也可是私有的(private)它们可以象任何c成员函数一样被调用可以传递任何类型的参数。不同在于一个槽函数能和一个信号相连接只要信号发出了这个槽函数就会自动被调用。connect函数语法如下:connect(sender,SIGNAL(signal),receiver,SLOT(slot))sender和receiver是QObject对象指针signal和slot是不带参数的函数原型。SIGNALE()和SLOT()宏的作用是把他们转换成字符串。在目前有的例子中我们已经连接了不同的信号和槽。实际使用中还要考虑如下一些规则:、一个信号可以连接到多个槽:connect(slider,SIGNAL(valueChanged(int)),spinBox,SLOT(setValue(int)))connect(slider,SIGNAL(valueChanged(int)),this,SLOT(updateStatusBarIndicator(int)))当信号发出后槽函数都会被调用但是调用的顺序是随机的不确定的。、多个信号可以连接到一个槽connect(lcd,SIGNAL(overflow()),this,SLOT(handleMathError()))connect(calculator,SIGNAL(divisionByZero()),this,SLOT(handleMathError()))任何一个信号发出槽函数都会执行。、一个信号可以和另一个信号相连connect(lineEdit,SIGNAL(textChanged(constQString)),this,SIGNAL(updateRecord(constQString)))第一个信号发出后第二个信号也同时发送。除此之外信号与信号连接上和信号和槽连接相同。、连接可以被删除disconnect(lcd,SIGNAL(overflow()),this,SLOT(handleMathError()))这个函数很少使用一个对象删除后Qt自动删除这个对象的所有连接。信号和槽函数必须有着相同的参数类型这样信号和槽函数才能成功连接:connect(ftp,SIGNAL(rawCommandReply(int,constQString)),this,SLOT(processReply(int,constQString)))如果信号里的参数个数多于槽函数的参数多余的参数被忽略:connect(ftp,SIGNAL(rawCommandReply(int,constQString)),this,SLOT(checkErrorCode(int)))如果参速类型不匹配或者信号和槽不存在在debug状态时Qt会在运行期间给出警告。如果信号和槽连接时包含了参数的名字Qt将会给出警告。以前我们列举的例子中都是控件的信号和槽。但是信号和槽机制在QObject中就实现了可以实现在任何从QObject继承的子类中。classEmployee:publicQObject{QOBJECTpublic:Employee(){mySalary=}intsalary()const{returnmySalary}publicslots:voidsetSalary(intnewSalary)signals:voidsalaryChanged(intnewSalary)private:intmySalary}voidEmployee::setSalary(intnewSalary){if(newSalary!=mySalary){mySalary=newSalaryemitsalaryChanged(mySalary)}}注意只有newSalary!=mySalary时才发出salaryChanged()信号这样避免了死循环的出现。×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××Qt的MetaObject系统Qt的一个最主要的成功是对C扩展即把彼此独立的软件模块连接起来而不需要模块间的任何细节。这个机制就是MetaObject系统它提供了两个关键的用途:信号和槽和introspection(内省)。introspection功能允许应用程序在运行时得到QObjec它子类的“metainformation”这对实现信号和槽是很必要的包括全部信号和槽的列表和类的名字。这个机制还提供了属性(在QtDesigner中使用)和文本翻译(国际化)支持。它们构成了QSA(QtScriptforApplication)的基础。标准C不提供Qtmetaobject系统需要的动态metainformation。Qt提供了一个独立的工具moc通过定义QOBJECT宏实现到C函数的转变。moc是用纯c实现的因此可以使用在任何C编译器中。这个机制工作过程如下:QOBJECT声明了一些QObject子类必须实现的内省函数:metaObject()TR()qtmetacall()等。Qt的moc工具实现QOBJECT宏声明的函数和所有的信号。QObject成员函数connect()和disconnect()使用这些内省函数实现信号和槽的连接。以上这些是通过qmakemoc和QObject自动处理的程序员通常不用考虑它们。如果你感到对此好奇可以查看QMetaObject类文档和moc实现的c代码。快速设计对话框(RapidRapidRapidRapidDialogDialogDialogDialogDesignDesignDesignDesign)通常程序员们都是用c源代码编写Qt应用程序Qt也是很容易用来编写的。然而许多程序员更喜欢用可视化的方法设计对话框这样能更快速更容易对对话框进行修改。QtDesigner满足了程序员的这一要求提供了可视化设计对话框的方法。它可以给一个应用程序提供全部或者部分对话框。用QtDesigner设计的对话框和用c代码写成的对话框是一样的可以用做一个常用的工具并不对编辑器产生影响。在这一节中我们使用QtDesigner创建GotoCell对话框无论用编写代码的方式还是用QtDesigner创建对话框都有如下基本的步骤:、创建和初始化子控件。、把子控件放到布局管理器中。、设置tab顺序。、创建信号和槽。、实现对话框的自己的槽函数。在windows平台Qt的安装目录的bin目录下点击desingerexe或者在unix平台在命令行上输入designer。当QtDesigner启动后它会列出一个控件模板的列表选择一个模板进入设计。**************************原文中对QtDesigner的介绍略去不想翻译了只要稍有点界面编程基础的都可以轻松使用。如果确实需要以后再补上。我个人不喜欢使用这个东东因为要多一个文件要维护当然如果要频繁修改所设计的对话框那这种方法还是很方便的。但不管怎么样最终都要修改源代码。所以我还是比较喜欢用源代码的方式把控件手工写出来。我想主要介绍把对话框设计好以后保存为ui文件后的处理。**************************假如设计好的文件保存在gotocell目录中命名为gotocelldialogui中然后在同一个目录下创建一个maincpp文件编码如下:#include<QApplication>#include<QDialog>#include"uigotocelldialogh"intmain(intargc,char*argv){QApplicationapp(argc,argv)Ui::GoToCellDialoguiQDialog*dialog=newQDialoguisetupUi(dialog)dialog>show()returnappexec()}保存后在该目录下运行qmake创建pro文件然后运行qmakeproject生成makefile文件。qmake可以发现gotocelldialogui文件然后就会调用uic(Qt的用户界面编译器)uic工具把gotocelldialogui转换成c代码保存在uigotocelldialogh中。在uigotocelldialogh中包含了Ui::GoToCellDialog类的定义这个类和gotocelldialogui等价。这个类声明成员变量存储对话框的子控件和布局管理器setupUi()函数初始化对话框。这个类的定义看起来有点象下面这个样子:classUi::GoToCellDialog{public:QLabel*labelQLineEdit*lineEditQSpacerItem*spacerItemQPushButton*okButtonQPushButton*cancelButtonvoidsetupUi(QWidget*widget){}}这个类没有父类。使用时创建一个QDialog把它传递给setupUi()函数。运行这个程序对话框将会显示出来但是有些功能它还不能实现:、Ok按钮是不可用状态的、Cancel按钮不作任何事情、编辑框除可以输入许可的字符或者数字外还可以输入任何文本我们可以编写代码让这个对话框变得有用起来。最直接的方法是创建一个新类继承QDialog和Ui::GoToCellDialog补上缺少的功能。(这说明任何软件问题可以通过添加一层间接包装来简单解决)。通常命名新类规则是把去掉uic生成的类名去掉Ui::前缀。创建gotocelldialogh头文件写下如下代码:#ifndefGOTOCELLDIALOGH#defineGOTOCELLDIALOGH#include<QDialog>#include"uigotocelldialogh"classGoToCellDialog:publicQDialog,publicUi::GoToCellDialog{QOBJECTpublic:GoToCellDialog(QWidget*parent=)privateslots:voidonlineEdittextChanged()}#endif新建gotocelldialogcpp源文件实现这个类:#include<QtGui>#include"gotocelldialogh"GoToCellDialog::GoToCellDialog(QWidget*parent):QDialog(parent){setupUi(this)QRegExpregExp("AZaz{,}")lineEdit>setValidator(newQRegExpValidator(regExp,this))connect(okButton,SIGNAL(clicked()),this,SLOT(accept()))connect(cancelButton,SIGNAL(clicked()),this,SLOT(reject()))}voidGoToCellDialog::onlineEdittextChanged(){okButton>setEnabled(lineEdit>hasAcceptableInput())}在构造函数中我们调用setupUi()初始化这个对话框。由于多继承我们可以直接使Ui::GoToCellDialog的成员。创建了用户界面以后我们可以把子控件的信号和槽函数连接起来。在构造函数中我们还创建一个许可器(validator)限制编辑框输入的范围。Qt提供了三个许可器类:QIntValidatorQDoubleValidator和QRegExpValidator。这里我们使用了QRegExpValidator使用的表达式为“AZaz{,}”这个表达式的意思是第一个字符输入为大写或者小写字母第二个字符为一个数字范围是到第三个字符是一个数字范围为到。在QRegExpValidator的构造函数中第二个参数为this把当前类作为它的父控件这样就可以不用删除它父控件析构时可以被自动删除。Qt的父子机制在QObject中实现的。当我们创建一个带有父的对象(如一个子控件一个许可器布局管理器等)时父对象把子对象放到自己的子对象列表中。父对象被删除时它查找自己的子对象并把每一个删除掉。这些子对象再把自己的子对象删除掉如此递归知道删除所有对象。这种父子对象的机制简化了内存管理减少了内存泄漏的危险。需要程序员删除的对象就是我们使用new创建的没有父对象的对象。如果我们在父对象存在时删除了它的一个子对象Qt将会在父列表中自动删除。(需要记住的是Qt只是删除有父的对象父对象还是需要手动删除的还有就是那些用new申请的没有指定父的内存一般情况下在对话框里的子控件许可器和布局管理器由Qt自己管理其他还要程序员小心删除)对于控件来讲父对象还有一个意义:子控件在父对象的显示区域内显示。当父控件删除后子控件不但在内存中被删除它也同时在屏幕上消失。在构造函数的最后两行把QDialog的accept()函数连接到OK按钮的点击信号把Cancel按钮的点击信号连接到reject()函数。这两个槽函数都关闭这个对话框但是accept()返回QDialog::Accepted(值为)reject()返回值为QDialog::Rejected(值为)。不同的返回值可以判断用户点击了那个按钮。onlineEdittextChanged()槽函数控制Ok按钮的可用状态通过编辑框中的输入字符如果字符有效Ok按钮则有效否则为不可用状态。QLineEdit::hasAcceptableInput()根据我们在构造函数中设置的许可器返回bool值。这就完成了这个对话框现在重写这个maincpp文件:#include<QApplication>#include"gotocelldialogh"intmain(intargc,char*argv){QApplicationapp(argc,argv)GoToCellDialog*dialog=newGoToCellDialogdialog>show()returnappexec()}编译这个程序(qmakeprojectqmakegotocellpro)然后运行。输入“A”Ok按钮变为可用。试着输入一行随意字符观察许可器的反映。点击Cancel按钮关闭这个对话框。使用qtDesigner可以不改变源程序的情况下改变对话框的设计。如果对话框用C代码编写改变它将会很费力的。使用QtDesigneruic自动重新生成源文件。不会浪费任何时间。能够改变的对话框(ShapeChanging(ShapeChanging(ShapeChanging(ShapeChangingDialogs)Dialogs)Dialogs)Dialogs)前面几章我们设计的对话框都是不能改变它的样子的。但是有时需要对话框根据要求进行适当的改变。两个最常用的需要改变的对话框是可扩展对话框和多页对话框。这两种类型的可以通过代码编写也可以用QtDesigner设计。可扩展对话框通常外观简单带有一个可扩展按钮来切换对话框的简单外观和可扩展外观。这种对话框通常为了迎合普通用户和高端用户而设计的如果没有特别请求隐藏高级应用部分。在这一节我们使用QtDesigner设计一个可扩展对话框。对话框是一个表格程序的排序对话框对用户选择的一些列按要求排列。对话框的简单外观允许用户输入一个简单排序关键词扩展部分允许输入两个额外的排序关键词。一个More按钮使用户在简单外观和扩展外观进行切换。我们使用QtDesigner创建这个可扩展的对话框在运行时刻隐藏高级功能这个看起来很复杂的对话框用QtDesigner可以很容易实现。首先设计好第一个关键词第二个和第三个关键词通过复制就可以得到:、启动File|New菜单选择“DialogwithButtonsRight”模板。、创建More按钮并将它托到右边的垂直布局管理器中放到垂直空白的下面。设置按钮的文本属为“More”它的checkable属性为“true”设置Ok按钮的default属性为true。、创建一个组合框两个标签两个下拉组合框和一个水平空白先把它们放在对话框的任何地方。、把组合框拖动大些把中其他控件拖动到其中按比例调整位置。、第二个下拉框宽度调整为第一个下拉框的二倍。、设置组合框的title属性为“PrimaryKey”第一个标签的text属性为“Column:”第二个标签的text属性为“Order:”。、设置第一个下拉框的第一个项目文本项为“None”。、设置第二个下拉框的项目为“Ascending”和“Descending”两个项目即升序和降序排列。、选择组合框设置它的布局为Grid。如果设计过程中出现错误可以选择Edit|Undo或者Form|BreakLayout重新进行排列。当然只要看起来不是很难看也可以是其他的样子只要易于理解就是ok。现在加入第二个第三个关键词:、把对话框拖动到足够大。、复制第一个组合框粘贴两次一次拖动到下面。、把复制的两个组合框的title属性为“SecondaryKey”和“TertiaryKey”。、在第一个关键词和第二个关键词组合框之间添加一个垂直空白。、调整添加的控件。、选择这个对话框降它设置为Grid管理。、设置两个垂直空白的sizeHint属性为,。按照下图命名每一个控件。命名对话框为sortDialog窗口标题为“Sort”。然后设置控件的tab顺序。从上到下点击下拉框然后点击OkCancelMore按钮。以上是对话框的设计。然后用QtDesigner建立控件的信号连接。因为我们创建对话框时使用了“DialogwithButtonsRight”模板Ok和Cancel按钮已经连接到了对话框的accept()和reject()槽函数。连接可以在Qtdesigner的signalslot编辑窗口查看。我们需要自己建立的连接是连接More按钮和secondaryGroupBox。将按钮的toggled(bool)信号和组合框的setVisible(bool)连接。选择Edit|SignalSlots将编辑状态变为连接态拖动More按钮到secondaryGroupBox上弹出信号编辑对话框。创建一个sort目录保存对话框文件到sort目录的sortdialogui使用多继承的方式使用这个对话框。首先新建一个sortdialogh头文件代码如下:#ifndefSORTDIALOGH#defineSORTDIALOGH#include<QDialog>#include"uisortdialogh"classSortDialog:publicQDialog,publicUi::SortDialog{QOBJECTpublic:SortDialog(QWidget*parent=)voidsetColumnRange(QCharfirst,QCharlast)}#endif然后新建sortdialogcpp源文件:#include<QtGui>#include"sortdialogh"SortDialog::SortDialog(QWidget*parent):QDialog(parent){setupUi(this)secondaryGroupBox>hide()tertiaryGroupBox>hide()layout()>setSizeConstraint(QLayout::SetFixedSize)setColumnRange('A','Z')}voidSortDialog::setColumnRange(QCharfirst,QCharlast){primaryColumnCombo>clear()secondaryColumnCombo>clear()tertiaryColumnCombo>clear()secondaryColumnCombo>addItem(tr("None"))tertiaryColumnCombo>addItem(tr("None"))primaryColumnCombo>setMinimumSize(secondaryColumnCombo>sizeHint())QCharch=firstwhile(ch<=last){primaryColumnCombo>addItem(QString(ch))secondaryColumnCombo>addItem(QString(ch))tertiaryColumnCombo>addItem(QString(ch))ch=chunicode()}}在构造函数中隐藏了第二个和第三个关键词部分。设置对话框的sizeConstraint的属性为QLayout::setFixedSize这样用户就不能随便改变对话框的大小。下面是maincpp文件:#include<QApplication>#include"sortdialogh"intmain(intargc,char*argv){QApplicationapp(argc,argv)SortDialog*dialog=newSortDialogdialog>setColumnRange('C','F')dialog>show()returnappexec()}编译运行这个程序点击More按钮查看对话框的改变。另一种可以改变的对话框是多页对话框。这类对话框也可以用两种方式创建。相关的类有QTabWidgetQStackedWidgetQListWidgetQTreeWidget等以后介绍。动态对话框(DynamicDynamicDynamicDynamicDialogsDialogsDialogsDialogs)动态对话框是在程序运行时用QtDesigner的ui文件创建。不用uic工具把ui文件变成等价的c代码而是在程序时使用类QUiLoader加载ui文件例如下面的代码:QUiLoaderuiLoaderQFilefile("sortdialogui")QWidget*sortDialog=uiLoaderload(file)if(sortDialog){}子控件可以用QObject::findChild<T>()得到QComboBox*primaryColumnCombo=sortDialog>findChild<QComboBox*>("primaryColumnCombo")if(primaryColumnCombo){}findChild<T>()是模板成员函数得到类型为T的给定名字的子控件的指针。由于编译器的原因用MSVC是得不到的。如果使用的是MSVC那么可以使用全局函数qFindChild<T>()。QUiLoader类在一个单独的链接库中如果在一个应用程

用户评价(5)

  • ly20082526 感谢 太谢谢了

    2010-09-09 15:32:54

  • 172.16.205.11 非常感谢,好东西

    2010-08-10 20:42:21

  • eastwarm 非常感谢,希望这样的人多一点

    2009-07-11 20:42:29

  • deepfish 多谢多谢~

    2009-04-16 23:18:19

  • 172.16.205.11 大哥,你的这种分享精神真的是太可贵了,太感谢你了,如果人人献出一点资源,网络将变得更美好

    2009-04-05 05:14:40

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/34

QT4中文手册

仅供在线阅读

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利