2.QT-窗口組件(QWidget),QT座標系統,初探消息處理(信號與槽)

本章主要內容以下:app

  • 1) 窗口組件(QWidget)
  • 2) QT座標系統
  • 3) 消息處理(信號與槽)

 


 

窗口組件(QWidget)函數

介紹測試

  • Qt以組件對象的方式構建圖形用戶界面
  • Qt中沒有父組件的頂級組件,則被叫作窗口
  • 組件的類型分爲:
  • 容器類(父組件)  :  用於包含功能的界面組件
  • 功能類(子組件)  :  用於實現特定的交互功能

以下圖所示:ui

 

好比上面的QgroupBox ,即屬於頂級組件的功能類(子組件),又是3個功能類組件的父組件(容器)this

 

組件繼承spa

Qt中全部窗口組件繼承於QWidget類,而QWidget類繼承於QObject類QPaintDevice類.操作系統

 

以下圖所示(只舉例了3個窗口組件類):3d

 

 

QWidget組件介紹code

  • QWidget可以繪製本身(由於繼承了QPaintDevice類),也可以處理用戶的輸入,好比點擊按鈕
  • QWidget是Qt窗口組件類的父類
  • Qt中每一個窗口組件均可以當作一個QWidget (由於子類能夠初始化父類)
  • QWidget類對象常做爲父組件頂級組件使用

 

初探QWidget對象

1)新建工程,選擇Qt Gui應用,設置類信息:

 

 

2)生成QWidget模板

運行模板:

 

能夠看到生成了一個窗口,而後咱們來看看模板代碼,是如何生成的.

 

3)模板代碼以下所示

#include <QtGui/QApplication>

#include "widget.h"

int main(int argc, char *argv[])

{

    QApplication a(argc, argv);

    QWidget w;                 //建立QWidget類對象

    w.show();                  //顯示QWidget類對象

   

    return a.exec();

}

根據以前講的內容能夠發現,因爲上面的QWidget w對象沒有父組件,因此QWidget w便成爲了沒有父組件的頂級組件,從而生成了窗口.

 

Qt座標系統

介紹

  • Qt使用統一的座標系統定位窗口部件的位置和大小
  • QWidget類爲組件類提供了窗口部件所需的座標系統成員函數

在Qt裏,座標類型分爲

  • 頂級窗口部件的定位
  • 窗口內部件的定位
  • 窗口部件的大小設置

座標位置示意圖,以下所示

 

  

QWidget類提供的經常使用座標系統成員函數有:

  • resize() :   設置窗口內部的寬高( width()和height()值)
  • move() :   設置整個窗口的x,y座標( x()和y()值)
  • setGeometry() :  設置窗口內部的x,y,w,h(不包括標題和窗口邊框)
  • size()  :  獲取窗口部件的大小
  • pos() :   獲取窗口部件的位置
  • x()  :      獲取整個窗口x座標
  • y()  :      獲取整個窗口y座標
  • width()  :   獲取窗口內部的寬度(不包括外邊框的寬度)
  • height()  :   獲取窗口內部的高度(不包括窗口標題欄的高度)
  • const QRect&  geometry ()  :   獲取窗口內部的x,y,w,h(不包括標題和窗口邊框)
  • const QRect&  framgeometry ()  :   獲取整個窗口的x,y,w,h

能夠參考下圖所示

 

注意: 在代碼裏,執行show()後, 再獲取 x,y,w,h座標 纔有效

 

接下來咱們經過3組不一樣的獲取座標函數,來打印(x,y,w,h)座標信息

代碼以下所示:

#include <QtGui>
#include "widget.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    QPushButton b("button",&w);   //生成 QPushButton對象, 其父組件爲 QWidget
/*設置窗口大小位置*/ w.resize(200,300); w.move(300,300);
/*設置按鈕大小位置*/ b.resize(100,50); b.move(50,100); w.show();
qDebug()
<<"QWidget:"; qDebug()<<"x()="<<w.x(); qDebug()<<"y()="<<w.y(); qDebug()<<"width()="<<w.width(); qDebug()<<"height()="<<w.height(); qDebug()<<"QWidget::geometry()"; qDebug()<<"x="<<w.geometry().x(); qDebug()<<"y="<<w.geometry().y(); qDebug()<<"w="<<w.geometry().width(); qDebug()<<"h="<<w.geometry().height(); qDebug()<<"QWidget::frameGeometry()"; qDebug()<<"x="<<w.frameGeometry().x(); qDebug()<<"y="<<w.frameGeometry().y(); qDebug()<<"w="<<w.frameGeometry().width(); qDebug()<<"h="<<w.frameGeometry().height(); return a.exec(); }

運行打印:

QWidget:
x()= 300
y()= 300
width()= 200
height()= 300

QWidget::geometry()
x= 308
y= 330
w= 200
h
= 300 QWidget::frameGeometry() x= 300 y= 300 w= 216 h= 338

 能夠看到,獲取的窗內座標(x,y)永遠比窗外座標大,窗外大小(w,h)永遠比窗內大小大

 

初探消息處理(信號與槽)

QT封裝了具體操做系統的消息機制,以下圖所示:

 

 

 

Qt中定義了與系統信息相關的概念

信號(signal)

  • 由操做系統產生的消息,好比按鍵消息

槽(slot)

  • 程序中的消息處理函數,用來處理信號,好比處理按鍵點擊信號

鏈接(Connect)

  • 將系統信息綁定到信息處理函數(信號到槽的鏈接),經過connect()函數實現,且必須發生在兩個Qt類對象之間,以下圖所示:

                                     

 

connect()函數原型

bool QObject::connect (
        const QObject * sender,                 //發送對象
        const char * signal,                     //消息名(信息)
        const QObject * receiver,                //接收對象
        const char * method,                     //接收對象的成員函數(槽)
        Qt::ConnectionType type = Qt::AutoConnection ) ;   //正常狀況不須要設置 //當出現sender對象的signal信號,則會自動調用receiver對象的method
//鏈接成功,則返回true;不然返回false。

 

在信號與槽裏,Qt引進了幾個新的關鍵字:

  • SIGNAL :指定消息名(信號),用於connect()函數裏
  • SLOT   : 指定消息處理函數名(槽),用於connect()函數裏
  • Q_OBJECT : 指定該類擁有槽(消息處理),在類聲明的內部開始處加上Q_OBJECT便可
  • slots  : 用於在類中聲明消息處理函數,好比:
private slots:
         void buttonCliked();

 

初探信號與槽

經過點擊按鈕,使程序自動退出,代碼以下所示:

#include <QtGui>
#include <QApplication>
#include <QPushButton>

int main(int argc,char * argv[])
{
  QApplication app(argc,argv);
  QPushButton *quitButton = new QPushButton("Quit");

  QObject::connect(quitButton, SIGNAL(clicked()), &app, SLOT(quit()));
  //*quitButton(發送對象), &app(接收對象)
  //quit()做用是退出程序, QApplication的成員函數
  //clicked()做用是鼠標點擊, 不少經常使用組件的成員函數

    quitButton->show();
    return app.exec();
}

其中上面的quit() 和clicked()都是系統預約義好的,接下來咱們自定義槽

首先須要注意

    • 類中聲明槽(處理信號的成員函數)時,須要slots聲明
    • 槽和信號的函數參數必須一致,好比clicked()和quit()都是無參數的
    • SIGNAL和SLOT指定的函數(信號和槽)只能包含參數類型,不能包含參數名

 

開始試驗,經過不一樣按鈕點擊,來打印不一樣的信息

寫QButtonDebug.h:

#ifndef QBUTTONDEBUG_H
#define QBUTTONDEBUG_H

#include
<QWidget> #include <QPushButton> class QButtonDebug : public QWidget { Q_OBJECT //指定該類擁有slots(槽) private: QPushButton *mbton1; QPushButton *mbton2; private slots: //經過slots 聲明 槽 void buttonCliked(); public: explicit QButtonDebug(QWidget *parent=0,Qt::WindowFlags f=0); }; #endif

 

寫QButtonDebug.cpp:

#include "QButtonDebug.h"
#include <QDebug>
QButtonDebug:: QButtonDebug(QWidget *parent,Qt::WindowFlags f) : QWidget(parent,f) //顯示初始化父類 { mbton1 = new QPushButton("button1",this); mbton2 = new QPushButton("button2",this); /*設置按鈕座標*/ mbton1->resize(100,50); mbton1->move(50,50); mbton2->resize(100,50); mbton2->move(50,100); /*設置鏈接*/ QObject::connect(mbton1,SIGNAL(clicked()),this,SLOT(buttonCliked())); QObject::connect(mbton2,SIGNAL(clicked()),this,SLOT(buttonCliked())); QWidget::show(); }
void QButtonDebug:: buttonCliked()           //消息處理函數 { QPushButton* p_buton =dynamic_cast<QPushButton*>(sender()); //獲取發送信號的對象 使用 qDebug()<< p_buton->text(); //更據不一樣的按鈕 打印不一樣信息 }

 

寫main.cpp

#include <QtGui>
#include <QApplication>
#include "QButtonDebug.h"

int main(int argc,char * argv[])
{
  QApplication a(argc, argv);

  QButtonDebug b(NULL,Qt::WindowCloseButtonHint);      
                     // Qt::WindowCloseButtonHint:去掉標題按鈕提示

  return a.exec();
}

 

運行測試

以下圖所示,能夠看到經過點擊不一樣的按鈕,便能打印不一樣的信息出來

 

 

深刻信號槽-自定義信號

介紹

  • 只有Qt類才能定義信號,且該類必須在頭文件中聲明
  • 信號函數只能經過signals關鍵字進行聲明,不能定義,且返回值必須是void類型
  • 信號函數的屬性會被自動設置爲protected類型
  • 發送信號時,只須要經過emit關鍵字調用信號函數便可
  • 若是信號函數的參數多於槽函數時,多於的參數將被忽略
  • 槽函數的返回值必須是void類型,且能夠被其它普通成員函數調用


自定義信號示例:

class MySignal : public QObject
{
  Q_OBJECT
signals:     //自定義信號函數
  void SendSignal(int i); 

public:
  void send(int i)
  {
    emit SendSignal(i); //調用信號函數,發送信號
  } 
};

自定義槽函數示例:

class MySlot : public QObject
{
  Q_OBJECT
protected slots:   void RecvSlot(int i)   {     qDebug()<<"Send:"<<sender()->objectName(); //打印發送對象名     qDebug()<<"Recv:"<<i;     qDebug()<<endl;   } };

 


信號與槽的組合

  • 信號函數能夠鏈接多個槽函數
  • 多個信號函數能夠鏈接一個槽函數
  • 一個信號就能夠鏈接到另外一個信號
  • 經過connect函數進行鏈接,也能夠經過disconnect函數取消鏈接

示例1-多個信號鏈接一個槽:

    MySignal s1;
    MySignal s2;
    MySlot t;

    s1.setObjectName("Signal1");
    s2.setObjectName("Signal2"); 
    QObject::connect(&s1,SIGNAL(SendSignal(int)),&t,SLOT(RecvSlot(int)));     QObject::connect(&s2,SIGNAL(SendSignal(int)),&t,SLOT(RecvSlot(int)));     s1.send(10);     s2.send(12);

打印:

Send: "Signal1" 
Recv: 10

Send: "Signal2" 
Recv: 12

 

示例2-信號1鏈接信號2,信號2鏈接槽:

    MySignal s1;
    MySignal s2;
    MySlot t;
    s1.setObjectName("Signal1");
    s2.setObjectName("Signal2");
    QObject::connect(&s1,SIGNAL(SendSignal(int)),&s2,SIGNAL(SendSignal(int)));
    QObject::connect(&s2,SIGNAL(SendSignal(int)),&t,SLOT(RecvSlot(int)));
    s1.send(10);
    s2.send(12);

打印:

    Send: "Signal2" 
    Recv: 10 
    Send:
"Signal2"     Recv: 12
相關文章
相關標籤/搜索