2011-06-28 17 views
6

tôi cố gắng để vẽ một hình chữ nhật tròn với drawRoundedRect phương pháp trực tiếp trong một QPixmap (không làm cho động cơ liên quan đến đây exept tinh khiết Qt một ...), tôi kiểm tra kích thước của hình chữ nhật so với kích thước của pixmap của tôi tăng gấp đôi:Hình chữ nhật tròn Qt, tại sao các góc khác nhau?

Pixmap : QSize(50, 73) 
Rectangle: QRect(0,0 48x11) 

Xem nhiều không gian ...

EDIT: một số mã

pixmap = QPixmap(50,73); //example size that match my case 
QRectF rect(0,0,48,11); 

QPainter painter(&pixmap); 
painter.setRenderHint(QPainter::TextAntialiasing); 
painter.setWorldMatrixEnabled(false); 
painter.setPen(QPen()); //no pen 
painter.setBrush(QBrush(color)); 
painter.drawRoundedRect(rect, 2.0, 2.0); 
  • tôi vô hiệu hóa chuyển đổi thế giới ...
  • tôi thiết lập thiết lập chuyển đổi để thống nhất ...
  • Tôi đã thử nhiều bán kính (1.0,2.0,3.0,4.0) ...
  • tôi thay đổi độ rộng bút, bàn chải màu ...

Nhưng nó luôn luôn kết thúc với một rectamgle với 4 góc khác nhau! Như thế:

Radius = 3.0 in x and y

tôi trực tiếp ouptut các pixmap vào một tập tin để chắc chắn tôi đã không cạo nó trong màn hình hiển thị ... cùng hình dạng.

Bất kỳ ai biết về hình chữ nhật tròn Qt có bán kính nhỏ? Tôi đã nhìn thấy mọi thứ về nó một thời gian dài trước đây nhưng tôi không nhớ làm thế nào để đối phó với nó!

Trả lời

14

Có vẻ như bạn không sử dụng tính năng chống răng cưa (tức là gợi ý hiển thị QPainter::Antialiasing). Đây là một quirk Qt xảy ra mà không có nó. Từ những gì tôi đã nhìn thấy/nghe, các nhà phát triển Qt không quan tâm đến việc sửa lỗi này (hầu hết mọi người đều muốn chống răng cưa).

Công việc xung quanh (ngoài việc chỉ sử dụng chống răng cưa) là tự vẽ trực tràng với QPainter::drawLine()QPainter::drawArc(). Bạn có thể phải chơi với các con số cho đến khi nó trông đúng - tính toán thẳng có xu hướng đi ra một điểm ảnh hoặc hai tắt. Ngoài ra, bạn có thể thấy rằng ngay cả với phương pháp này góc dưới bên phải không bao giờ là chính xác giống như các góc khác.

Nếu bạn cảm thấy hơi tham vọng, bạn có thể thử sửa lỗi này và gửi bản vá cho Qt.

Cập nhật: Kết quả bản vẽ Arc đã thay đổi trong Qt 5. Theo kinh nghiệm của tôi, đó là một cải tiến lớn.

+2

Tôi chơi với antialising cách khác để vẽ công cụ (drwa đường dẫn, vòng cung ...). Antialiasing với những thứ nhỏ như vậy làm cho nó có giá trị! Và cú đánh tốt nhất của tôi là addind ~ 0.5 mỗi khi quessing nơi rouding có thể tạo ra hành vi kỳ lạ ... Vì vậy, tôi sẽ chấp nhận ** play với số ** phương pháp! – vrince

+2

Đã xảy ra sự cố tương tự. Sử dụng 'QPainter p (this); p.setRenderHint (QPainter :: Antialiasing); p.setRenderHint (QPainter :: HighQualityAntialiasing); 'đã thực hiện thủ thuật cho tôi. –

+0

thay đổi chiều rộng bút làm phép thuật !! – Ashish

0

cố gắng phát với gợi ý hiển thị 1) vô hiệu hóa chống răng cưa; 2) bật SmoothPixmapTransform

nhưng vẫn không đảm bảo rằng nó sẽ giúp ích.

+0

chính xác đã nói, không đảm bảo !! – Ashish

3

thử thêm một nửa điểm ảnh bù đắp (ví dụ .: rect.translated(0.5,0.5)):

QRectF rect(0,0,48,11); 
painter.setRenderHint(QPainter::Antialiasing,false); 
painter.drawRoundedRect(rect.translated(0.5,0.5), 2.0, 2.0); 

Tôi cho rằng điều này đã làm với hệ tọa độ đặt một giá trị số nguyên giữa hai pixel.

Nếu bạn vẽ bằng cách chống răng cưa và sử dụng bút có độ rộng 1 pixel thì vẽ theo tọa độ nguyên chính xác sẽ dẫn đến các đường có chiều rộng 2 pixel thay thế. Chỉ với bù đắp 0,5 pixel này, bạn sẽ nhận được các đường chính xác rộng 1 pixel.

QRectF rect(0,0,48,11); 
painter.setRenderHint(QPainter::Antialiasing,true); 
painter.setBrush(Qt::NoBrush); 
painter.setPen(Qt::white); 
painter.drawRoundedRect(rect.translated(0.5,0.5), 2.0,2.0); 
2

Tôi biết đây là một vấn đề cũ nhưng đối với người dùng Qt5 gọi setRenderHint(QPainter::Qt4CompatiblePainting); trên QPainter dường như giải quyết vấn đề.

Edit:

Tôi tìm thấy một giải pháp để tạo ra một hình chữ nhật tròn hoàn hảo cùng với màu đường viền và nó trông giống như hình chữ nhật tròn được sử dụng bởi QPushButton 's biên giới ví dụ. Đây là cách tôi thực hiện các paintEvent để đạt được điều này:

void MyButtonGroup::paintEvent(QPaintEvent * e) 
{ 
    int borderSize = 5; 
    QColor borderColor = Qt::red; 
    QColor backgroundColor = Qt::blue; 
    int borderRadius = 3; 

    QPen pen; 
    pen.setWidth(borderSize); 
    pen.setColor(borderColor); 

    QPainter painter(this); 
    painter.setRenderHint(QPainter::Antialiasing); 
    painter.setPen(pen); 

    QRectF rect(rect().x() + borderSize/2, 
       rect().y() + borderSize/2, 
       rect().width() - borderSize, 
       rect().height() - borderSize); 


    if(borderSize % 2 == 0) 
    { 
     painter.drawRoundedRect(rect, 
           borderSize, 
           borderSize); 
    } 
    else 
    { 
     painter.drawRoundedRect(rect.translated(0.5, 0.5), 
           borderRadius, 
           borderRadius); 
    } 

    QBrush brush(backgroundColor); 
    pen.setBrush(brush); 
    painter.setBrush(brush); 

    if(borderSize % 2 == 0) 
    { 
     painter.drawRoundedRect(rect, 
           borderRadius, 
           borderRadius); 
    } 
    else 
    { 
     painter.drawRoundedRect(rect.translated(0.5, 0.5), 
           borderRadius, 
           borderRadius); 
    } 

    QWidget::paintEvent(e); 
} 

Tôi gửi bài này vì tôi thấy nó một chút khó khăn để đạt được kết quả này:

enter image description here

1

Cách tốt nhất làm vẽ RoundRect là Con đường. http://developer.nokia.com/community/wiki/Qt_rounded_rect_widget

void fillRoundRect(QPainter& painter, QRect r, int radius) 
{ 
    painter.setRenderHint(QPainter::Antialiasing,true); 

    QPainterPath rounded_rect; 
    rounded_rect.addRoundRect(r, radius, radius); 
    painter.setClipPath(rounded_rect); 

    painter.fillPath(rounded_rect,painter.brush());  
    painter.drawPath(rounded_rect);  
} 
0

Tôi đã thử tất cả các lời khuyên từ câu trả lời ở đây nhưng không làm việc cho tôi. Nhưng dựa trên các đoạn mã này tôi đã tìm thấy giải pháp sau:

Làm mặc định đặt m_pPainter->setRenderHint(QPainter::Qt4CompatiblePainting, true) và chỉ cho hình chữ nhật tròn có chiều rộng% 2 == 0 tắt nó.

QRect rect = ConvertRectangle(rectangle); 

int nPenWidth = m_pPainter->pen().width(); 
if (nPenWidth % 2 == 0) 
    m_pPainter->setRenderHint(QPainter::Qt4CompatiblePainting, false); 

m_pPainter->drawRoundedRect(rect, dbRadiusX, dbRadiusY); 

if (nPenWidth % 2 == 0) 
    m_pPainter->setRenderHint(QPainter::Qt4CompatiblePainting, true);