2013-01-10 33 views
7

Tôi có một số QTreeView và muốn màu nền khác nhau cho các hàng, tùy thuộc vào nội dung của chúng. Để đạt được điều này, tôi lấy một class MyTreeView từ QTreeView và thực hiện các phương pháp sơn như sau:Thay đổi màu nền của một hàng QTreeView không hoạt động

void MyTreeView::drawRow (QPainter* painter, 
           const QStyleOptionViewItem& option, 
           const QModelIndex& index) const 
    { 
     QStyleOptionViewItem newOption(option); 

     if (someCondition) 
     { 
     newOption.palette.setColor(QPalette::Base, QColor(255, 0, 0)); 
     newOption.palette.setColor(QPalette::AlternateBase, QColor(200, 0, 0)); 
     } 
     else 
     { 
     newOption.palette.setColor(QPalette::Base, QColor(0, 0, 255)); 
     newOption.palette.setColor(QPalette::AlternateBase, QColor(0, 0, 200)); 
     } 

     QTreeView::drawRow(painter, newOption, index); 
    } 

Ban đầu, tôi đặt setAlternatingRowColors(true); cho QTreeView.

Vấn đề của tôi: Đặt màu cho QPalette :: Cơ sở không có hiệu lực. Mỗi hàng thứ hai vẫn còn màu trắng.

Tuy nhiên, thiết lập QPalette :: AlternateBase hoạt động như mong đợi. Tôi đã thử setAutoFillBackground(true)setAutoFillBackground(false) mà không có bất kỳ ảnh hưởng nào.

Có bất kỳ gợi ý nào về cách giải quyết vấn đề này không? Cảm ơn bạn.


Ghi chú: Thiết lập màu sắc bằng cách thích ứng MyModel::data(const QModelIndex&, int role) cho Qt::BackgroundRole không cung cấp kết quả mong muốn. Trong trường hợp này, màu nền chỉ được sử dụng cho một phần của hàng. Nhưng tôi muốn tô màu toàn bộ hàng, bao gồm cả bên trái với các công cụ điều hướng cây.

Qt Version: 4.7.3


Cập nhật: Vì những lý do không rõ QPalette::Base có vẻ là đục. setBrush không thay đổi điều đó. Tôi tìm thấy cách giải quyết như sau:

if (someCondition) 
    { 
     painter->fillRect(option.rect, Qt::red); 
     newOption.palette.setBrush(QPalette::AlternateBase, Qt::green); 
    } 
    else 
    { 
     painter->fillRect(option.rect, Qt::orange); 
     newOption.palette.setBrush(QPalette::AlternateBase, Qt:blue); 
    } 

Trả lời

5

Thay vì subclassing QTreeView bạn nên xử lý màu nền qua mô hình của bạn. Sử dụng hàm data()Qt::BackgroundRole để thay đổi màu nền của các hàng.

QVariant MyModel::data(const QModelIndex &index, int role) const 
{ 
    if (!index.isValid()) 
     return QVariant(); 

    if (role == Qt::BackgroundRole) 
    { 
     if (condition1) 
      return QColor(Qt::red); 
     else 
      return QColor(Qt::green); 
    } 

    // Handle other roles 

    return QVariant(); 
} 
+1

Tôi cố gắng này, nhưng điều này không mang lại kết quả mong muốn. Với cách tiếp cận này, màu nền không được vẽ cho toàn bộ hàng, mà chỉ cho các mục cây. Nền của điều hướng cây (ở phía bên trái của các mục) không bị thay đổi. – SebastianK

+0

@SebastianK Tôi nghĩ rằng đây vẫn là cách đúng đắn, nhưng cách bạn thực hiện 'condition1' trong ví dụ này là chìa khóa.Ví dụ, bạn có thể làm 'if (index.sibling (index.row(), someColumnIndex) .data() == bất cứ điều gì) {...}'. Bạn phải chắc chắn rằng điều này không được gọi cho trường hợp 'index.column() == someColumnIndex' như là đệ quy vô hạn của khóa học. –

+0

@TimMeyer Tôi đã cố gắng với điều kiện 'điều kiện' ong luôn đúng. Nền của hàng chỉ có một phần màu đỏ. Đối với các mục mở rộng, phần bên trái của hàng vẫn là màu trắng. Với "phần bên trái", tôi có nghĩa là khu vực có các công cụ điều hướng cây (mở rộng/thu gọn [+]/[-] và dòng thành phụ huynh) – SebastianK

7

Nếu vấn đề duy nhất là việc mở rộng/thu gọn điều khiển không có một nền tảng như phần còn lại của hàng sau đó sử dụng Qt::BackgroundRole trong ::data() của mô hình của bạn (như mô tả của pnezis trong their answer) và thêm video này vào cây của bạn xem lớp học:

void MyTreeView::drawBranches(QPainter* painter, 
           const QRect& rect, 
           const QModelIndex& index) const 
{ 
    if (some condition depending on index) 
    painter->fillRect(rect, Qt::red); 
    else 
    painter->fillRect(rect, Qt::green); 

    QTreeView::drawBranches(painter, rect, index); 
} 

Tôi đã thử nghiệm điều này trên Windows (Vista và 7) sử dụng Qt 4.8.0 và mũi tên mở rộng/thu gọn có nền phù hợp. Vấn đề là các mũi tên đó là một phần của khung nhìn và do đó không thể được xử lý trong một mô hình.

+0

Cảm ơn câu trả lời của bạn. Như bạn đã nói, nhược điểm của giải pháp này là nó nằm rải rác giữa Model và View. Nhưng ý tưởng với 'fillRect' dẫn tôi đến một giải pháp hợp lý. – SebastianK

+1

Tôi đồng ý, trong trường hợp này, tốt hơn là chỉ nên có mã màu trong chế độ xem - ghi đè các hàm thành viên drawXXX khác. Tôi rất vui vì tôi có thể giúp. –

0

https://www.linux.org.ru/forum/development/4702439

if (const QStyleOptionViewItemV4* opt = qstyleoption_cast<const QStyleOptionViewItemV4*>(&option)) 
{ 
     if (opt.features & QStyleOptionViewItemV4::Alternate) 
      painter->fillRect(option.rect,option.palette.alternateBase()); 
     else 
      painter->fillRect(option.rect,painter->background()); 
} 
Các vấn đề liên quan