Qt中如何对控件实现整体缩放和界面复制?

phoenices 2013-11-08 12:45:29
标题中的整体缩放指的是,当改变控件大小时,控件带着内部所有视觉元素,作为一个整体缩放,就像变成了它自己的缩略图一样,但缩放后的控件仍然能正常操作;类似于WPF中的Viewbox控件;
标题中的界面复制指的是,制作一个控件的缩略图,放在另一个图像类控件上显示。当然:1.这个缩略图是实时的;2.整体缩放功能是必须有的;3.就算源控件的一部分或全部因为(被遮挡、不在父容器窗口内、没有设置父容器从而没有加入可视树)等原因不可见,只要该界面本身存在,就存在正常的缩略图。类似于WPF中的VisualBrush类。
Qt中是否内置了提供相应功能的类?没有的话,能否自己方便的实现?
谢谢,因为可用分不多,所以只能在有效答案出来后再加分,望谅解,加分能让您满意的
...全文
993 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
RabinSong 2013-11-11
  • 打赏
  • 举报
回复
那就只能重载resizeEvent了,在重载事件里根据父窗口布局大小,来相应缩放子控件的大小 QObjectList *pChildList = this->children();//找到所有的孩子,再判断孩子是否是派生自QWidget,只有这样的孩子,才是窗体,才能对窗体缩放, 可以通过 setGeometry() resize 等方法实现缩放 如果你要实现鼠标放在控件上,你需要重载,mouse hover事件。
phoenices 2013-11-11
  • 打赏
  • 举报
回复
引用 4 楼 rjsloth 的回复:
第一个问题,控件中如果没有其他控件,可以重新实现控件的paintEvent事件处理函数,通过setWindow函数和setViewport函数的组合使用来达到整体缩放的效果,这很简单。但是如果控件中还有其他控件,就意味着你需要在resize父控件的同时,重新设置其所有子控件的pos和size,而且子控件的paintEvent事件处理函数也要和父控件一样setWindow和setViewport,那么,你需要在父控件的sizeEvent事件处理函数中告诉其所有子控件重新设置pos和size。这个就麻烦一点,但是应该还是可以实现的。 另外对第一个问题补充一下,如果可能,你也可以不用子控件,而是通过自己画的方式在特定位置画出“子控件”并根据位置等信息让这些“子控件”对事件作出响应,这样你实际上只定义了一个控件,但是这个控件看上去是里面有很多子控件。 第二个问题,用render函数应该可以很轻松的解决。
谢谢。 第一个问题,我要缩放的是一个根控件,所有可操作控件都是它的子级。另一方面,如果采用“画”的方式,虽然还是可以响应鼠标事件,但是应该没法把光标定位到一个“画”出来的文本框里面还让它在里面一闪一闪的,所以看起来只能采用你第一段后半部分说的方案。还有一个问题是字体的缩放,假设控件未缩放的时候某个字符宽高都是20,控件宽缩放为4/5,高缩放为2/3,那经过这样缩放之后能变成宽16,高13.33的压扁的字符吗? 然后对于这个方案和render函数,能给出一个Demo吗?我没有搜索到render函数的用法
rjsloth 2013-11-11
  • 打赏
  • 举报
回复
#include <QApplication> #include <QWidget> #include <QPainter> #include <QPushButton> class Shower: public QWidget { public: Shower(QWidget* copyWidget, QWidget* parent = 0): QWidget(parent), m_pCopyWidget(copyWidget) { } ~Shower() { } protected: void paintEvent(QPaintEvent *event) { m_pCopyWidget->render(this); } private: QWidget* m_pCopyWidget; }; class ScaleWidget: public QWidget { public: ScaleWidget(QWidget* parent = 0): QWidget(parent) { resize(400, 200); } ~ScaleWidget() { } protected: void paintEvent(QPaintEvent *event) { QPainter painter(this); /* painter.setWindow(-50, -50, 100, 100); painter.setViewport(0, 0, width(), height()); */ painter.setWindow(-50, -50, 100, 100); int minLength = width() < height() ? width() : height(); painter.setViewport((width() - minLength) >> 1, (height() - minLength) >> 1, minLength, minLength); painter.fillRect(-10, -10, 20, 20, Qt::red); painter.drawText(-50, -50, 30, 100, Qt::AlignCenter, "TEST"); } }; int main(int argc, char** argv) { QApplication app(argc, argv); QWidget mainWidget; mainWidget.resize(650, 150); QPushButton* pButtonA = new QPushButton("ButtonA", &mainWidget); pButtonA->resize(150, 50); pButtonA->move(50, 50); QPushButton* pButtonB = new QPushButton("ButtonB", &mainWidget); pButtonB->resize(150, 50); pButtonB->move(250, 50); Shower* pShower = new Shower(pButtonA, &mainWidget); pShower->resize(150, 50); pShower->move(450, 50); pShower->connect(pButtonA, SIGNAL(clicked()), SLOT(update())); pShower->connect(pButtonB, SIGNAL(clicked()), SLOT(update())); mainWidget.show(); ScaleWidget scaleWidget; scaleWidget.show(); return app.exec(); }
rjsloth 2013-11-11
  • 打赏
  • 举报
回复
首先,由于你的子widget有字符编辑控件,所以纯自己画的话,确实比较麻烦,但实际上应该还是可以的,不过这个没必要继续深究了。 然后,关于使用setWindow和setViewport之后,字体是否会等比例缩放,是可以等比例缩放的,也可以不等比例缩放,关键在于你是如何设置setWindow和setViewport中对应的区域的高宽比。下一楼的代码中,ScaleWidget的paintEvent函数中,没注释掉的设置是字符会等比缩放的情况,注释掉的设置是字符会被压缩的情况。 最后,关于render,我的代码中,让pShower总是拷贝显示pButtonA上显示的内容,你可以通过点击两个按钮来观看pShower上的显示情况,可以通过pButtonA是否获得焦点来验证pShower上显示的是pButtonA的内容。代码中的两个connect是为了让pShower实时显示pButtonA的内容。 把我下一楼的回复贴到某个cpp文件中,建个空工程,然后跑一下这个cpp文件就可以了。代码写得比较仓促,不严谨的地方不用深究。
rjsloth 2013-11-09
  • 打赏
  • 举报
回复
第一个问题,控件中如果没有其他控件,可以重新实现控件的paintEvent事件处理函数,通过setWindow函数和setViewport函数的组合使用来达到整体缩放的效果,这很简单。但是如果控件中还有其他控件,就意味着你需要在resize父控件的同时,重新设置其所有子控件的pos和size,而且子控件的paintEvent事件处理函数也要和父控件一样setWindow和setViewport,那么,你需要在父控件的sizeEvent事件处理函数中告诉其所有子控件重新设置pos和size。这个就麻烦一点,但是应该还是可以实现的。 另外对第一个问题补充一下,如果可能,你也可以不用子控件,而是通过自己画的方式在特定位置画出“子控件”并根据位置等信息让这些“子控件”对事件作出响应,这样你实际上只定义了一个控件,但是这个控件看上去是里面有很多子控件。 第二个问题,用render函数应该可以很轻松的解决。
phoenices 2013-11-08
  • 打赏
  • 举报
回复
对应的是第一个问题吗?这个测试代码是如何演示的?我拖拉窗口大小,按钮只是宽度跟着窗口变化,不符合我的要求。我需要的是类似于将鼠标放在Win7任务栏图标上弹出来的缩略图那样,包括控件大小、控件坐标、字体等所有可视元素都被同步缩放的效果
RabinSong 2013-11-08
  • 打赏
  • 举报
回复
#include <QApplication> #include <qgroupbox.h> #include <QMouseEvent> #include <qwidget.h> #include <qdebug.h> #include <qdialog.h> #include <qlayout.h> #include <qpushbutton.h> class CDlg : public QWidget { public: CDlg(QWidget *parent = NULL) : QWidget(parent) { QGroupBox *pgb = new QGroupBox("test", this); QPushButton *ppbOk = new QPushButton("test", this); QHBoxLayout *phLayout = new QHBoxLayout(pgb); phLayout->addWidget(ppbOk); phLayout = new QHBoxLayout(this); phLayout->addWidget(pgb); } }; int main(int argc, char**argv) { QApplication app(argc,argv); CDlg dlg; dlg.resize(500, 500); dlg.show(); return app.exec(); } 以上应该是你要的结果。
RabinSong 2013-11-08
  • 打赏
  • 举报
回复
#include <QApplication> #include <qgroupbox.h> #include <QMouseEvent> #include <qwidget.h> #include <qdebug.h> #include <qdialog.h> #include <qlayout.h> #include <qpushbutton.h> class CGroupBox : public QGroupBox { public: CGroupBox(QWidget *parent = NULL) : QGroupBox(parent) { } protected: void mousePressEvent(QMouseEvent *event) { qDebug() << event->pos(); } }; class CDlg : public QDialog { public: CDlg(QWidget *parent = NULL) : QDialog(parent) { CGroupBox *pgb = new CGroupBox(this); pgb->setTitle("test"); QPushButton *ppbOk = new QPushButton("test", this); QHBoxLayout *phLayout = new QHBoxLayout(pgb); phLayout->addWidget(ppbOk); phLayout = new QHBoxLayout(this); phLayout->addWidget(pgb); } }; int main(int argc, char**argv) { QApplication app(argc,argv); CDlg dlg; dlg.resize(500, 500); dlg.exec(); return app.exec(); }

16,211

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧