首页 > 代码库 > QT GUI总结

QT GUI总结

QT提供了设计师工具,可以很方便的使用鼠标拖拽的方式绘制界面。绘制完毕后自动生成一个界面的.h文件(如ui_mainwindow.h),其中含有一个自动生成的Ui_MainWindow类,这个类中核心的函数是setupUi,根据界面向导的不同里面接收一个QWidget *参数或者QMainWindow *参数。这个函数会自动在传入的QWidget或QMainWindow上根据设计师绘制的界面创建可视化控件。使用这个自动生成的类有两种方式,一是在定义QWidget或QMainWindow时创建一个Ui_MainWindow类型的成员ui,在构造函数中调用其setupUi方法ui.setupUi(this),或使用C++特有的多继承方式,定义子类的时候同时以Ui_MainWindow作为基类,在构造函数中直接调用setupUi(this).这时已经可以在自定义部件子类中显示绘制的界面了。要访问绘制界面的可视化控件,根据上述两种方式使用ui->控件名称或者控件名称直接进行引用即可。

  这时显示已经没问题了,我们还需要设置界面元素的信号-槽,使之可以响应事件。QT提供了一种默认信号-槽对应关系:on_控件名称_信号函数名称(参数列表).当定义了这样的函数后,QT会将函数自动与界面控件的信号相关联,当控件触发了相关事件后这个函数将会被触发.另外一种方式是直接使用QObject::connect函数来关联信号和槽.语法为:

connect(发出信号的对象指针,SIGNAL(信号函数原型), 响应信号的对象, SLOT(槽函数原型));

  这里先说说信号及槽与普通成员函数有什么区别,只是定义的区域不同而已.信号函数需要声明在头文件的signals:关键字后面,无需实现.而槽则需要定义在public/private slots:关键字后面,实现与正常函数一样,可以直接调用,当然调用权限与slots前面的范围控制关键字(public/private)有关.这里强调几点:

  1)一个信号可以多次使用connect函数与多个槽关联,信号触发后这些槽不能保证调用顺序,但都会执行一遍.

  2)多个信号可以连接同一个槽.

  3)信号之间可以互相关联(语法为 connect(对象1,SIGNAL(信号函数原型), 对象2, SIGNAL(信号函数原型))),当第一个信号触发另一个信号也会触发

  4)使用disconnect函数移除信号-槽的关联

  5)信号与槽的参数必须顺序一致,类型相同,如果信号的参数比槽的参数多,多余的参数被忽略,反之报错.

  6)信号与槽的机制不仅仅限于界面开发,普通的类也可以声明信号和槽,并建立关联

触发信号的语法为:  emit 信号名称(实参列表);

  使用布局机制组织界面元素:布局控件有QHBoxLayout,QVBoxLayout及QGridLayout.分别是水平布局,垂直布局和网格布局控件.其他控件可放置与其上,当窗体大小改变的时候会自动调整界面元素位置和大小.QT还提供了一个伸展器控件,放置与布局控件的空闲部位使其他元素位置总是居上或居下.

  在主窗体上创建菜单栏,工具栏:在头文件中声明QAction对象,每个QAction对应一个菜单栏、工具栏对象。在构造函数中实例化这些Action并将其显示在菜单栏或工具栏上。

  newAction = new QAction(tr("&New"), this);

  newAction->setIcon(QIcon(":/images/new.png"));//设置资源中的图片文件作为其图标

  newAction->setShortcut(QKeySequence::New);//设置快捷键 键值与系统有关

  newAction->setStatusTip(tr("Create a new spreadsheet file"));//鼠标经过时显示在状态栏上的文字

  connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));//设置信号-槽关联

  fileMenu = menuBar()->addMenu(tr("&File"));//创建顶层菜单 文件菜单

  fileMenu->addAction(newAction);//将上面创建的Action添加到菜单上

  fileToolBar = addToolBar(tr("&File"));//创建工具栏

  fileToolBar->addAction(newAction);//将上面创建的Action添加到工具栏上

  如果要创建部件的右键菜单,需要将Action添加到部件,并设置部件的上下文菜单的策略.更高级的实现方式是重写部件的contextMenuEvent方法,创建一个QMenu窗口,在其中添加动作后调用exec()函数.

  部件对象->addAction(newAction);

  部件对象->setContextMenuPolicy(Qt::ActionsContextMenu);

  设置状态栏首先需要向状态栏添加控件用来显示信息.

  locationLabel = new QLabel("W999");

  locationLabel->setAlignment(Qt::AlignHCenter);

  locationLabel->setMinimumSize(locationLabel->sizeHint());

  locationLabel->setIndent(3);//设置扩展因子,在状态栏大小发生变化是自动调整区域,默认扩展因子为0,表示大小不发生变化.

  statusBar()->addWidget(locationLabel);//向状态栏添加控件

    QT启动画面(Splash)用于在程序启动的时候显示信息并等待启动完毕后取消显示.需要写在main()函数中:

  QSplashScreen *splash = new QSplashScreen();

  splash->setPixmap(‘:/images/splash.png‘);

  splash->show();

  Qt::Alignmeng topRight = Qt::AlignRight | Qt::AlignTop;

  splash->showMessage(QObject.tr("要显示的信息"), topRight, Qt::white);

   //后面可多次调用showMessage方法向用户显示不同信息.使用完毕关闭之.

  splash->finish(&mainWin);//将控制权交给mainWin窗体

  delete splash;

  QMainWindow的中央窗口部件属性用于指定主窗体中央区域显示的部件,这些部件可以是普通的多行控件,自定义的窗体部件,带布局管理的部件,或切分窗口的QSplitter部件,或用于实现MDI风格的QMdiArea部件.这里说说MDI风格的窗体实现.首先从QMainWindow类继承一个子类,在子类的构造函数中:

  mdiArea = new QMdiArea();

  setCentralWidget(mdiArea);

  mdiArea->addSubWindow(部件类型指针);//将部件(QWidget类型)添加到区域中作为一个子窗口

  mdiArea->activeNextSubWindow();//使下一个子窗体为当前活动窗体

  mdiArea->activeSubWindow()返回当前子窗体

  mdiArea->setActiveSubWindow(子窗体对象指针)//设置当前子窗体.子窗体对象必须包含在mdiArea中,否则报错.

  通过上面的函数基本上可以实现MDI窗体了,但是子窗体的打开关闭,或当前子窗体发生变化,都会影响主菜单及工具栏中各项的状态,这里需要灵活应用信号-槽机制,在发生状态变化的时候调整Enabled属性.

  自定义QT控件:在继承QWidget实现了特定功能可视化部件后,可以使用插件的方式将其加入QT设计师工具中,这样就可以在设计器用鼠标拖放的方式将自定义的部件添加的窗体中了.首先需要从QDesignerCustomWidgetFnterface继承一个子类,重写几个函数指定控件的名称,所在的组,提示信息等,关键的函数是createWidget方法,返回特定窗口部件的实例.最后在插件源文件的末尾添加Q_EXPORT_PLUGIN2宏将插件注册到设计师.

  QT4极大的改善了绘图的刷新效率,但在及特殊情况下也需要使用双缓冲区机制,思路是创建一个QPixmap,需要绘制的图形现在其上绘制完毕后,在触发paintEvent事件时直接将这个pixMap刷到屏幕的图像区域之上.

  QT的事件机制:要处理对象的事件,可以重写QObject::event()函数,这个函数会将特定事件进行分发,如鼠标事件mousePressEvent,键盘事件keyPressEvent,及paintEvent等,如果关心特定事件也可以重写这些事件.如果需要定时触发的timer机制,可以重写timerEvent函数.首先int myTimeId = startTimer(时间间隔ms);在timerEvent中:if(event->timerId() == myTimeId) {...........}

  QT提供了事件监控机制,在构造函数中调用 对象1->installEventFilter(对象2);这样就可以使用对象2来监控对象1的事件,对象2重写其eventFilter函数,通过target参数来确定事件的发出者,并可以对事件进行干预.QT的事件是从子对象向父对象传递的,如果子对象处理了事件则停止传递.需要注意的是installEventFilter函数是定义在QObject上的,所以可以在QApplication上设置事件监控,控制整个应用程序的事件.重写QApplication::notify()函数可在事件刚发出就截获事件.如果在密集运行时希望界面响应事件,需要调用QApplication::processEvents();方法.

给Qt工程生成的可执行文件添加图标

1.  找一个ico文件,该名为适当的。如EXEICON.ico。 
2.  手动创建一个对应的rc文件。如EXEICON.rc: 
       IDI_ICON1 ICON DISCARDABLE "EXEICON.ico" 
3.  将上面两个文件放在当前目录,把HdssMap.rc加入工程在中。重新生成即可。

给Qt窗体添加图标

在main函数中:

 QApplication a(argc, argv);
 a.setWindowIcon(QIcon(":/DataManager/Resources/statics.png"));

给Qt程序设置默认皮肤:

 QApplication a(argc, argv);
 a.setStyle("windowsxp");

还可设置为:"windows","motif","cde","motifplus","platinum","sgi"和"compact".根据平台,"windowsxp","aqua"或"macintosh"也是可以用的。

Qt中计算一段程序的运行时间:

#include <QTime>

QTime tmpTime;

tmpTime.start();

qDebug() << tmpTime.elapsed() << "ms";