久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

使用 QStyledItemDelegate::paint() 直接在 QListView 上繪制

Paint widget directly on QListView with QStyledItemDelegate::paint()(使用 QStyledItemDelegate::paint() 直接在 QListView 上繪制小部件)
本文介紹了使用 QStyledItemDelegate::paint() 直接在 QListView 上繪制小部件的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

工作數小時后,我可以在 QListView 上繪制小部件.但是,繪制是通過QPixmap 完成的.小部件出現,我可以看到一個進度條.然而,它有點像素化"(由于使用了QPixmap).是否可以直接作為普通小部件進行繪制?這是我的問題.

After hours of work, I'm able to paint a widget on QListView. However, the painting is done through a QPixmap. The widget appears, and I can see a progress bar. However, it's a little "pixelated" (due to using QPixmap). Is it possible to paint directly as a normal widget? That's my question.

以下是我所做的:

void FileQueueItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QPaintDevice* original_pdev_ptr = painter->device();

    FileQueueListItem* itemWidget = reinterpret_cast<FileQueueListItem*>(index.data(Qt::UserRole).value<void*>());

    itemWidget->setGeometry(option.rect);
    painter->end();

    QPixmap pixmap(itemWidget->size());
    if (option.state & QStyle::State_Selected)
        pixmap.fill(option.palette.highlight().color());
    else
        pixmap.fill(option.palette.background().color());
    itemWidget->render(&pixmap,QPoint(),QRegion(),QWidget::RenderFlag::DrawChildren);

    painter->begin(original_pdev_ptr);
    painter->drawPixmap(option.rect, pixmap);
}

我從此處學習了如何使用提示進行操作.在那里,繪畫是直接在 QListView 上完成的,這正是我想要實現的.以下嘗試不起作用,我做錯了什么:

I learned how to do what I did with the hints from here. There, the painting is done directly on QListView, which is what I'm looking to achieve. What am I doing wrong for the following attempt not to work:

void FileQueueItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    std::cout<<"Painting..."<<std::endl;
    QPaintDevice* original_pdev_ptr = painter->device();

    FileQueueListItem* itemWidget = reinterpret_cast<FileQueueListItem*>(index.data(Qt::UserRole).value<void*>());

    itemWidget->setGeometry(option.rect);
    painter->end();

    if (option.state & QStyle::State_Selected)
        painter->fillRect(option.rect, option.palette.highlight());
    else
        painter->fillRect(option.rect, option.palette.background());

    itemWidget->render(painter->device(),
                       QPoint(option.rect.x(), option.rect.y()),
                       QRegion(0, 0, option.rect.width(), option.rect.height()),
                       QWidget::RenderFlag::DrawChildren);
    painter->begin(original_pdev_ptr);
}

列表只是空著,什么也沒有發生.雖然可以看到選擇,但小部件不顯示.

The list just remains empty, and nothing happens. Though the selection can be seen, but the widget doesn't show up.

推薦答案

讓我們把一些事情說清楚:

Let's make a few things clear:

  1. 您不應該創建小部件并將它們放入模型中.這有一個很好的理由.Qt 事件循環中涉及小部件,這意味著擁有過多小部件會顯著降低您的程序速度.

  1. You're not supposed to create widgets and put them in a model. There's a very good reason for this. Widgets are involved in the Qt event loop, which means that having too many widgets will significantly slow down your program.

小部件不僅僅是一堆控件(這似乎是您看待它們的方式).它們參與事件循環,這就是為什么您不應該擁有屬于數據模型一部分的小部件.

Widgets are not simply a bunch of controls (which seems to be how you see them). They take part in the event loop, which is why you should not have a widget that's a part of a data model.

如果您使用的是多線程程序并且我們的模型與視圖分離,那么內存管理將成為一場噩夢.Qt 永遠不會容忍嘗試從其他線程構造或刪除任何小部件(這是有道理的,因為從事件循環中分離線程通常不是線程安全的).

If you're using a multithreaded program and you have our model separated from the view, memory management will become a nightmare. Qt will never tolerate trying to construct or delete any widgets from other threads (which makes sense, since detaching threads from the event loop is not generally thread-safe).

根據這些信息,做您想做的事情的正確方法是什么?遺憾的是,唯一正確的方法是自己繪制控件.如果您的小部件很簡單,那很容易做到.如果您的小部件很復雜,您將需要大量數學運算來計算每個小部件的位置.

Given this information, what's the right way to do what you're trying to do? Sadly the only correct way is to draw the controls yourself. If your widget is simple, that's easy to do. If your widget is complicated, you're gonna need lots of math to calculate the positions of every widget.

在 Qt Torrent 示例中,您將看看進度條是如何繪制的.繪制控件所需要做的就是計算位置,并使用rect 成員變量作為控件的包含矩形,然后繪制它們(當然,在設置它們的值之后).paint() 函數中有一個 option.rect 參數,它是整個項目的矩形.您所要做的就是使用一些數學方法來計算每個小部件在此矩形內的位置.

In the Qt Torrent Example, you'll see how a progress bar is drawn. All you have to do to draw your controls, is calculate the position, and use the rect member variable as the containing rectangle of the controls, and then draw them (of course, after setting their values). The function paint() has an option.rect parameter in it, which is the rectangle of the whole item. All you have to do, is use some math to calculate the positions inside this rect for every widget.

PS:永遠不要對位置使用絕對值.你永遠不會做對,尤其是對于不同的 DPI.

PS: NEVER USE ABSOLUTE VALUES FOR THE POSITIONS. You will never get it right, especially for different DPIs.

這將在沒有小部件的情況下繪制控件,并且即使對于數千個元素也能保證您所需的速度.

That will draw the controls without widgets, and will guarantee the speed you need even for thousands of elements.

這篇關于使用 QStyledItemDelegate::paint() 直接在 QListView 上繪制小部件的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

How can I read and manipulate CSV file data in C++?(如何在 C++ 中讀取和操作 CSV 文件數據?)
In C++ why can#39;t I write a for() loop like this: for( int i = 1, double i2 = 0; (在 C++ 中,為什么我不能像這樣編寫 for() 循環: for( int i = 1, double i2 = 0;)
How does OpenMP handle nested loops?(OpenMP 如何處理嵌套循環?)
Reusing thread in loop c++(在循環 C++ 中重用線程)
Precise thread sleep needed. Max 1ms error(需要精確的線程睡眠.最大 1ms 誤差)
Is there ever a need for a quot;do {...} while ( )quot; loop?(是否需要“do {...} while ()?環形?)
主站蜘蛛池模板: 日本欧美国产在线 | 久久伊人精品一区二区三区 | 久久99久久99 | 国产伦一区二区三区久久 | 国产精品久久国产精品久久 | 国产精品污www一区二区三区 | 国产精品我不卡 | 日本三级全黄三级三级三级口周 | 99re国产视频 | 欧美精品片| 成人一区二区三区在线观看 | 91成人影院| 欧美乱大交xxxxx另类电影 | 国产一区二区不卡 | 欧美日韩视频在线 | 久久久久久久一区二区三区 | 91av视频| 亚洲综合久久久 | 国产日韩精品视频 | 一道本不卡 | 国产成人免费观看 | 久久国| 中文字幕免费中文 | www.xxxx欧美 | 欧美日韩精品一区 | 亚洲精彩视频在线观看 | 亚洲一区久久 | 国产区在线 | 日本特黄a级高清免费大片 成年人黄色小视频 | 少妇午夜一级艳片欧美精品 | 成人久久久 | 午夜爽爽爽男女免费观看影院 | 老子午夜影院 | 色综合欧美| 婷婷色网 | 日韩成人在线视频 | 国产精品久久久久久影院8一贰佰 | 国产精品一区二区三区久久 | 久久国际精品 | 亚洲视频一区二区三区四区 | 欧美日韩综合 |