在Qt应用程序的上下文中,我使用以下代码片段截取完整桌面的屏幕截图:
QDesktopWidget* dw = QApplication::desktop();
QPixmap pixmap = QPixmap::grabWindow(dw->winId(), 0, 0,
dw->width(), dw->height());
pixmap.save(name, "JPG", screenshot_quality);
这种方法在Linux和Windows中非常有效,并且具有双显示器,与屏幕分辨率无关;也就是说,如果两个显示器使用不同的分辨率,它仍然有效。但是,使用Qt 5,我得到以下运行时警告:
static QPixmap QPixmap::grabWindow(WId, int, int, int, int) is deprecated, use QScreen::grabWindow() instead. Defaulting to primary screen.
所以我回顾了Qt 5 doc并写了这篇文章:
QScreen * screen = QGuiApplication::primaryScreen();
QPixmap pixmap = screen->grabWindow(0);
pixmap.save(name, "JPG", screenshot_quality);
但这种方法无法捕获第二个屏幕。
所以我搜索了一下,根据这个帖子Taking Screenshot of Full Desktop with Qt5,我设计了截图截图如下:
QScreen * screen = QGuiApplication::primaryScreen();
QRect g = screen->geometry();
QPixmap pixmap = screen->grabWindow(0, g.x(), g.y(), g.width(), g.height());
pixmap.save(name, "JPG", screenshot_quality);
不幸的是,这也行不通。
引起我注意的是Qt 4的方法效果很好。因为我认为必须有一些方法可以在Qt 5中实现它。
所以,我的问题是如何用Qt 5完成?
编辑:这是我解决的方式:
QPixmap grabScreens()
{
QList<QScreen*> screens = QGuiApplication::screens();
QList<QPixmap> scrs;
int w = 0, h = 0, p = 0;
foreach (auto scr, screens)
{
QRect g = scr->geometry();
QPixmap pix = scr->grabWindow(0, g.x(), g.y(), g.width(), g.height());
w += pix.width();
h = max(h, pix.height());
scrs.append(pix);
}
QPixmap final(w, h);
QPainter painter(&final);
final.fill(Qt::black);
foreach (auto scr, scrs)
{
painter.drawPixmap(QPoint(p, 0), scr);
p += scr.width();
}
return final;
}
感谢@ddriver!
答案 0 :(得分:4)
当然,QGuiApplication::primaryScreen()
会为您提供一个屏幕。
您可以使用QList<QScreen *> QGuiApplication::screens()
获取与应用程序关联的所有屏幕,为所有屏幕截取屏幕截图,然后创建另一个空白图像,根据您想要组成屏幕的方式调整大小,然后手动构建使用QPainter
的最终图片。
QPixmap grabScreens() {
auto screens = QGuiApplication::screens();
QList<QPixmap> scrs;
int w = 0, h = 0, p = 0;
foreach (auto scr, screens) {
QPixmap pix = scr->grabWindow(0);
w += pix.width();
if (h < pix.height()) h = pix.height();
scrs << pix;
}
QPixmap final(w, h);
QPainter painter(&final);
final.fill(Qt::black);
foreach (auto scr, scrs) {
painter.drawPixmap(QPoint(p, 0), scr);
p += scr.width();
}
return final;
}
答案 1 :(得分:1)
或者您可以使用虚拟几何(QScreen :: virtualGeometry())并用一行(或两行)代码捕获所有屏幕):
public async Task<ActionResult> GetPopularContent(int Records, int? WorkareaRef, string Jurisdiction)
{
var model = new PopularContentModel();
int? languageId = null;
var login = new Login(HttpContext);
var branding = new DynamicBranding(login);
if (branding.BrandingDefaultLanguage != Cam.Service.ContentService.defaultLanguageId)
{
languageId = branding.BrandingDefaultLanguage;
}
languageId = languageId ?? ContentService.defaultLanguageId;
var jurisdictionRef = string.IsNullOrEmpty(Jurisdiction) ? (int?)null : metaDataService.GetJurisdictionRefViaName(Jurisdiction);
var reads24 = (await mostPopularContentService.MostPopularLast24HoursAsync(languageId.Value, WorkareaRef, jurisdictionRef, Records + 30)).ToDictionary(x=>x.Article, x=>x.Total);
var reads7 = (await mostPopularContentService.MostPopularThisWeekAsync(languageId.Value, Records + 30)).ToDictionary(x => x.Article, x => x.Total);
var readsShared = (await mostPopularContentService.MostSharedThisWeekAsync(languageId.Value, Records + 30)).ToDictionary(x => x.Article, x => x.Total);
model.Read7DayDataSource = articleService.GetArticlesFromGuidList(reads7.Select(x=>x.Key), wcagOnly: branding.StrictlyWCAG2Accessible, useCache: true)
.Select(x => new PopularArticle() { Article = x, ArticleGuid = x.ArticleGUID })
.Where(x=> contentAdminTestingDataFilterService.AllowFirmAccess(x.Article.FirmRef, lexUser) && x.Article.RemoveDate == null)
.OrderByDescending(x=> reads7[x.ArticleGuid])
.Take(Records)
.ToArray();
model.Read24DataSource = articleService.GetArticlesFromGuidList(reads24.Select(x => x.Key), wcagOnly: branding.StrictlyWCAG2Accessible, useCache: true)
.Select(x => new PopularArticle() { Article = x, ArticleGuid = x.ArticleGUID })
.Where(x => contentAdminTestingDataFilterService.AllowFirmAccess(x.Article.FirmRef, lexUser) && x.Article.RemoveDate == null)
.OrderByDescending(x => reads24[x.ArticleGuid])
.Take(Records)
.ToArray();
model.SharedDataSource = articleService.GetArticlesFromGuidList(readsShared.Select(x => x.Key), wcagOnly: branding.StrictlyWCAG2Accessible, useCache: true)
.Select(x => new PopularArticle() { Article = x, ArticleGuid = x.ArticleGUID })
.Where(x => contentAdminTestingDataFilterService.AllowFirmAccess(x.Article.FirmRef, lexUser) && x.Article.RemoveDate == null)
.OrderByDescending(x => readsShared[x.ArticleGuid])
.Take(Records)
.ToArray();
model.LastUpdated = DateTime.Now.AddDays(-1).Date;
DecorateFirmName(model);
model.ShowSocialButtons = branding.ShowSocialButtons;
return PartialView("PopularContentPartial", model);
}