2010-12-10 42 views
10

我正在使用Qt 4.7 QPainter繪製一些多邊形,等等到一個小部件。我希望改變座標系使得(0,0)位於我的小部件的中心,並且x/y軸以標準的「笛卡爾」方式運行(即,y增加「向上」並減小「下」)。換句話說,如果你知道我的意思,我希望座標是「數學」,而不是「計算機圖形」。 :-)使用窗口/視口翻轉QPainter y軸

我正在嘗試使用setViewport()和setWindow()來做這件事,而不是自己做數學,因爲它能夠直接用我的座標直接調用繪圖方法。

這裏是我到目前爲止有:

// Setup coordinates 
double screenWidth = width(); 
double screenHeight = height(); 

double windowWidth = 100.0; 
double windowHeight = (screenHeight/screenWidth) * windowWidth; 

painter.setViewport(0, 0, screenWidth, screenHeight); 
painter.setWindow(-(windowWidth/2.0), -(windowHeight/2.0), windowWidth, windowHeight); 

// Draw stuff 
painter.setPen(Qt::NoPen); 
painter.setBrush(Qt::blue); 
painter.drawRect(-10, -10, 20, 20); 

現在,這工作得很好,因爲它吸引一個漂亮的藍色方塊在屏幕的中間。問題是,我不得不說,左上角是(-10,-10)。我希望能夠做到這一點(-10,10),因爲這就是笛卡爾座標系中的情況。

我試圖搞亂setWindow/setViewport來得到這個「y軸翻轉」,但無濟於事。這似乎是一件非常簡單/基本的事情,但在淘汰Qt文檔和網頁之後,我無法弄清楚!

謝謝,
克里斯

回答

22

使用類QMatrix。它指定了2D轉換。 QMatrix設置爲QPainter

但要記住,你的情況,如果轉換Widget的COORDS到笛卡爾COORDS,你將不得不把第一點(-10,-10)(不(-10,10 )因爲你沒有提到的)繪製一個矩形,其在(0,0中心),因爲Y軸現在長大了 X軸現在的增長

所有你需要的是這種方式將您的座標系統:

  • 翻譯起源(0,0)對小部件的中間:
    alt text

  • 規模Y軸-1因子:
    alt text

下面是代碼,在窗口小部件的paintEvent()功能類型:

QPainter pn(this); 

int w_2 = width()/2; 
int h_2 = height()/2; 

{ // X- and Y-Axis drawing 
    pn.setPen(Qt::blue); 
    pn.drawLine(0, h_2, width(), h_2);  // X-Axis 
    pn.drawLine(w_2, 0 , w_2, height()); // Y-Axis 
} 

QMatrix m; 
m.translate(w_2, h_2); 
m.scale(1, -1); 

pn.setMatrix(m); 
pn.setPen(Qt::NoPen); 
pn.setBrush(QBrush(Qt::blue, Qt::Dense4Pattern)); 
pn.drawRect(-10, -10, 20, 20); 

結果:
alt text

更新2014年4月7日

這問題很久以前就被問到了許多事情自那以來已經改變對於那些今天(2014年初)他們自問相同的問題,我個人的回答是,自Qt 4.3以後,可以更輕鬆地解決文本翻轉問題。

你說得對。文本也被填滿,因爲它是用同一個畫家繪製的。如果可能,可以在所有翻轉圖紙完成時在最後繪製文本。由於文本位置的新計算,此方法不方便。你也需要放棄畫家的設置。 現在我建議你使用QGraphicsView,因爲2D繪畫的巨大支持。也可以設置每個QGraphicsItemItemIgnoresTransformations標誌,該標誌允許忽略繼承的轉換(即,其位置仍然錨定到其父項,但忽略父視圖或視圖旋轉,縮放或剪切轉換)。此標誌對於保持文本標籤項目水平和非縮放非常有用,因此如果圖形視圖已轉換,它們仍然可讀。

+1

正確,但是需要提及的是,文本也會翻轉。這大多是不期望的! – bkausbk 2014-03-24 12:50:11

+0

感謝您的更新;) – Stormenet 2014-12-09 17:06:13

3

上述答案也將翻轉文本,「p」將爲「b」。爲避免在繪製文本之前必須翻轉y軸,並且繪製文本時必須在y座標上更改文本位置的符號。我覺得這有點難看,還是有更好的辦法?

1

如上所述,繪圖文字也會翻轉翻轉。有一個簡單的解決方案,見下文。我們將臨時禁用文本繪圖的世界變換。請注意,文字不再縮放。

在您的繪畫代碼中,我們要在座標QPointF P上繪製文本;

Painter pn(this); 

// calculate the point with the transform 
QPointF p = pm.transform().map(P); 

// Disable Transform temporary 
pn.setWorldMatrixEnabled(false); 

// draw it ordinary, no scaling etc 
pn.drawText(p, QString("HI FRIENDS!")); 

// Enable the transform again 
pn.setWorldMatrixEnabled(true);