是否有可能使所有人都画到一个区域" A"被翻译成一个区域" B"?
例如绘制到区域(0,0)(100,100)并将其显示在区域(200,200)(300,300)中。
答案 0 :(得分:2)
问题实际上是使用windows和graphics标记的。这可能是针对Win32和GDI(我很遗憾几乎没有经验)。因此,以下可能被视为概念证明:
我无法抗拒使用QWindow
和QPixmap
来实现这个想法/概念。
概念是:
全屏打开一个窗口(即没有装饰)
制作快照并将其存储在内部(在我的情况下为a)
在窗口中显示内部图像(用户无法注意到差异)
执行一个循环,其中pixmap被修改并定期重新显示(取决于或不取决于用户输入)。
这就是我在Qt中的表现:
我打开QWindow
并将其全屏显示。 (最大尺寸可能会使窗口全屏显示,但仍然会有装饰(带有系统菜单的标题栏等),这是无意的。)
在绘制任何内容之前,此窗口的快照已完成。使用QScreen::grabWindow()
在Qt中这很容易。抓取的内容将返回QPixmap
并存储为我的派生Window
类的成员。
视觉输出只绘制存储的成员QPixmap
。
我使用QTimer
来强制QPixmap
的定期更改。为了使示例代码尽可能短,我没有努力改变瓦片。相反,我只是滚动像素图复制一小部分,向上移动其余部分,再次在底部插入小条纹。
示例代码qWindowRoll.cc
:
#include <QtWidgets>
class Window: public QWindow {
private:
// the Qt backing store for window
QBackingStore _qBackStore;
// background pixmap
QPixmap _qPixmap;
public:
// constructor.
Window():
QWindow(),
_qBackStore(this)
{
showFullScreen();
}
// destructor.
virtual ~Window() = default;
// disabled:
Window(const Window&) = delete;
Window& operator=(const Window&) = delete;
// do something with pixmap
void changePixmap()
{
enum { n = 4 };
if (_qPixmap.height() < n) return; // not yet initialized
const QPixmap qPixmapTmp = _qPixmap.copy(0, 0, _qPixmap.width(), n);
//_qPixmap.scroll(0, -n, 0, n, _qPixmap.width(), _qPixmap.height() - n);
{ QPainter qPainter(&_qPixmap);
qPainter.drawPixmap(
QRect(0, 0, _qPixmap.width(), _qPixmap.height() - n),
_qPixmap,
QRect(0, n, _qPixmap.width(), _qPixmap.height() - n));
qPainter.drawPixmap(0, _qPixmap.height() - n, qPixmapTmp);
}
requestUpdate();
}
protected: // overloaded events
virtual bool event(QEvent *pQEvent) override
{
if (pQEvent->type() == QEvent::UpdateRequest) {
paint();
return true;
}
return QWindow::event(pQEvent);
}
virtual void resizeEvent(QResizeEvent *pQEvent)
{
_qBackStore.resize(pQEvent->size());
paint();
}
virtual void exposeEvent(QExposeEvent*) override
{
paint();
}
// shoot screen
// inspired by http://doc.qt.io/qt-5/qtwidgets-desktop-screenshot-screenshot-cpp.html
void makeScreenShot()
{
if (QScreen *pQScr = screen()) {
_qPixmap = pQScr->grabWindow(winId());
}
}
private: // internal stuff
// paint
void paint()
{
if (!isExposed()) return;
QRect qRect(0, 0, width(), height());
if (_qPixmap.width() != width() || _qPixmap.height() != height()) {
makeScreenShot();
}
_qBackStore.beginPaint(qRect);
QPaintDevice *pQPaintDevice = _qBackStore.paintDevice();
QPainter qPainter(pQPaintDevice);
qPainter.drawPixmap(0, 0, _qPixmap);
_qBackStore.endPaint();
_qBackStore.flush(qRect);
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
// setup GUI
Window win;
win.setVisible(true);
// setup timer
QTimer qTimer;
qTimer.setInterval(50); // 50 ms -> 20 Hz (round about)
QObject::connect(&qTimer, &QTimer::timeout,
&win, &Window::changePixmap);
qTimer.start();
// run application
return app.exec();
}
我在Windows 10上使用Qt 5.9.2编译和测试。这就是它的外观:
注意:在我的桌面上,滚动很流畅。我手动制作了4张快照并在GIMP中组成了一个GIF - 因此图像看起来有点卡顿。