pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

使用 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 ()?環形?)
主站蜘蛛池模板: Safety light curtain|Belt Sway Switches|Pull Rope Switch|ultrasonic flaw detector-Shandong Zhuoxin Machinery Co., Ltd | 山东限矩型液力偶合器_液力耦合器易熔塞厂家-淄博市汇川源机械厂 | Trimos测长机_测高仪_TESA_mahr,WYLER水平仪,PWB对刀仪-德瑞华测量技术(苏州)有限公司 | BOE画框屏-触摸一体机-触控查询一体机-触摸屏一体机价格-厂家直销-触发电子 | 超细粉碎机|超微气流磨|气流分级机|粉体改性设备|超微粉碎设备-山东埃尔派粉碎机厂家 | 橡胶粉碎机_橡胶磨粉机_轮胎粉碎机_轮胎磨粉机-河南鼎聚重工机械制造有限公司 | 哲力实业_专注汽车涂料汽车漆研发生产_汽车漆|修补油漆品牌厂家 长沙一级消防工程公司_智能化弱电_机电安装_亮化工程专业施工承包_湖南公共安全工程有限公司 | 北京四合院出租,北京四合院出售,北京平房买卖 - 顺益兴四合院 | 气动机械手-搬运机械手-气动助力机械手-山东精瑞自动化设备有限公司 | 小学教案模板_中学教师优秀教案_高中教学设计模板_教育巴巴 | 胀套-锁紧盘-风电锁紧盘-蛇形联轴器「厂家」-瑞安市宝德隆机械配件有限公司 | 商标转让-购买商标专业|放心的商标交易网-蜀易标商标网 | 机制砂选粉机_砂石选粉机厂家-盐城市助成粉磨科技有限公司 | 烟台金蝶财务软件,烟台网站建设,烟台网络推广 | 低浓度恒温恒湿称量系统,强光光照培养箱-上海三腾仪器有限公司 | 汽车润滑油厂家-机油/润滑油代理-高性能机油-领驰慧润滑科技(河北)有限公司 | 工业胀紧套_万向节联轴器_链条-规格齐全-型号选购-非标订做-厂家批发价格-上海乙谛精密机械有限公司 | 电镀整流器_微弧氧化电源_高频电解电源_微弧氧化设备厂家_深圳开瑞节能 | 一氧化氮泄露报警器,二甲苯浓度超标报警器-郑州汇瑞埔电子技术有限公司 | 英国雷迪地下管线探测仪-雷迪RD8100管线仪-多功能数字听漏仪-北京迪瑞进创科技有限公司 | 深圳法律咨询【24小时在线】深圳律师咨询免费 | 扬州汇丰仪表有限公司 | 薄壁轴承-等截面薄壁轴承生产厂家-洛阳薄壁精密轴承有限公司 | 办公室家具_板式办公家具定制厂家-FMARTS福玛仕办公家具 | 精准猎取科技资讯,高效阅读科技新闻_科技猎 | 云南外加剂,云南速凝剂,云南外加剂代加工-普洱澜湄新材料科技有限公司 | 生物制药洁净车间-GMP车间净化工程-食品净化厂房-杭州波涛净化设备工程有限公司 | 代理记账_公司起名核名_公司注册_工商注册-睿婕实业有限公司 | 青岛美佳乐清洁工程有限公司|青岛油烟管道清洗|酒店|企事业单位|学校工厂厨房|青岛油烟管道清洗 插针变压器-家用电器变压器-工业空调变压器-CD型电抗器-余姚市中驰电器有限公司 | 东莞压铸厂_精密压铸_锌合金压铸_铝合金压铸_压铸件加工_东莞祥宇金属制品 | 德州网站开发定制-小程序开发制作-APP软件开发-「两山开发」 | 精准猎取科技资讯,高效阅读科技新闻_科技猎 | 二手Sciex液质联用仪-岛津气质联用仪-二手安捷伦气质联用仪-上海隐智科学仪器有限公司 | 西安文都考研官网_西安考研辅导班_考研培训机构_西安在职考研培训 | 老房子翻新装修,旧房墙面翻新,房屋防水补漏,厨房卫生间改造,室内装潢装修公司 - 一修房屋快修官网 | 陶瓷砂磨机,盘式砂磨机,棒销式砂磨机-无锡市少宏粉体科技有限公司 | 筛分机|振动筛分机|气流筛分机|筛分机厂家-新乡市大汉振动机械有限公司 | 广东高华家具-公寓床|学生宿舍双层铁床厂家【质保十年】 | 必胜高考网_全国高考备考和志愿填报信息平台 | 焊管生产线_焊管机组_轧辊模具_焊管设备_焊管设备厂家_石家庄翔昱机械 | 物联网卡_物联网卡购买平台_移动物联网卡办理_移动联通电信流量卡通信模组采购平台? |