久久久久久久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 ()?環形?)
主站蜘蛛池模板: 国产一区二区精品在线观看 | 91视频88av | 成人一级毛片 | 欧美a在线看 | 欧美激情精品久久久久久变态 | 日韩免费高清视频 | 免费成人在线网站 | av手机在线播放 | 羞羞视频在线免费 | 亚洲成人网在线 | 久久精品一区二区视频 | 午夜精品一区二区三区在线观看 | 国产在线对白 | 欧美激情视频一区二区三区免费 | 久久涩涩 | 无吗视频| 中文在线亚洲 | 亚洲黄色国产 | 一级欧美 | 欧美猛交 | 日韩视频一区二区在线 | 日韩中文字幕一区二区 | 一级在线免费观看 | 免费国产一区 | 国产一区二区三区免费观看视频 | 久久综合国产精品 | 激情欧美一区二区三区中文字幕 | 一级网站 | 精品二三区 | 一级片免费视频 | 欧美精品一区二区三区在线 | 精品一区二区三区四区 | 一级午夜aaa免费看三区 | 国产黄色网址在线观看 | 一本一道久久a久久精品综合 | 国产黄色网址在线观看 | 又爽又黄axxx片免费观看 | 一区二区久久 | 日日干天天操 | 国产精品视频久久 | 国产精品美女久久久免费 |