1. 程式人生 > >QT中視口與視窗的概念理解

QT中視口與視窗的概念理解

看了一段間的QT,對視口與視窗的概念一直思不得其解,經過大量的閱讀網上資料和實踐,終於理解一二,記錄於此。 

在QT中 WIdget在構建並顯示以後會有一 個預設的大小,而此時其實已經存在視窗和視口,只是這兩者在沒有人為改變時大小是一樣的,所以你可以忽略二者的存在;QT在繪圖時是先在視窗中繪製然後再對映到視口上去的。 視口就是代表我們的物理視窗,視窗是代表繪圖區(QT的畫板)使用的邏輯座標。 在兩者相同的情況下也是一一對映關係,所以你會看到所畫即所得。 但是當兩者不同時,如果不理解就會覺得莫名其妙。如下程式碼:

TEST::TEST(QWidget *parent) : QWidget

(parent)

{

    setWindowTitle(QObject::tr("測試Widget"));

resize(200,200);

}

void TEST::paintEvent(QPaintEvent *event)

{

    QPainter painter(this);

    QPen pen(Qt::red);

    painter.setPen(pen);

    qDebug() << "viewport:\t x = " << painter.viewport().width() << "y = "

             <<

painter.viewport().height();

    qDebug() << "window:\t\t x = " << painter.window().width() << "y = "

             << painter.window().height();

    painter.drawRect(0,0,100,100);

    painter.drawLine(0,0, 100, 100);

//    painter.setViewport(0, 0, 100 ,100 );

//    painter.setWindow(0, 0,100,100);

    qDebug() << "set viewport:\t x = " << painter.viewport().width() << "y = "

             << painter.viewport().height();

    qDebug() << "set window:\t x = " << painter.window().width() << "y = "

             << painter.window().height();

    painter.drawRect(50,50, 50, 50);

     painter.drawLine(100,0, 0, 100);

}

以上所畫即所得,不用解釋即可明白, 需要注意的是,在沒有人為改變時,視口和視窗大小都是220x200的。

下面修改視口大小如下:

注意,此時視口大小為100x100, 但視窗大小仍為200x200, 所以對映時視窗會被縮小一倍進行繪製。 執行結果如下:

可以看到在改變視口後,繪製的正方形(50, 50, 50, 50)從起始座標到長度都被縮小一倍到物理視窗的(25,  25, 25, 25), 斜線從視窗的(100, 0, 0, 100)繪到了物理視窗的(50,0,0,50)位置。 從此可以看到,不僅是單純的大小變化,起始座標也被改變。

下面來改一下視窗,視口保持不變,程式碼如下:

注意此時我們只改變以了視窗大小,視口是沒有變的,還是200X200, 所以此時畫出來的圖會被放大一倍來顯示,結果如下:

可以看到在改變視窗,視口不變的情況下,繪製的正方形(50, 50, 50, 50)從起始座標到長度都被縮小一倍到物理視窗的(100, 100, 100, 100), 斜線從視窗的(100, 0, 0, 100)繪到了物理視窗的(200,0,0,200)位置。 從此可以看到,不僅是單純的大小變化,起始座標也被改變。

最後將兩都做如下修改:

此時,兩者又一樣了,但比原始視窗均小一倍,結果如下:

再將程式碼改為如下:

由上可以看到,小正方形和斜線在x, y方向上都偏移了10個畫素, 原因在於viewport的大小沒變,但位置從原來的(0,0)修改到了(10, 10), 但斜線和小正方形的相對位置是沒有變的。

再做如下修改:

這次的結果是出乎意料的, 可能你會覺得小正方形會變為(40, 40, 50, 50), 斜線會變為:(90, 0, 0, 90), 但實際結果為:小正方形卻實如下所述, 但斜線卻變為了(80, 0, 0 , 80),如下所示:

原因在於(100, 0, 0, 100)這條線與視窗(10,10,110, 110)的矩形區域交界大概在(90,10, 10, 90)這條線上,所以在視口上也只會對映此線段,而這邊線段在對映在視口中正是上面這個結果。

綜上實驗可以得出如下結論:

  1. 視窗的物理大小(resize(200, 200)),視口(viewport)以及視窗(window)大小是三個不同的概念。
  2. 視口即視窗物理大小上畫定的一塊區域,用於呈現繪圖結果。繪圖位置與視口位置相關。
  3. 視窗始終是以視口為對映物件的。對映關係是四個頂點一一對應進行對映。