作者:MiMe淘宝店 | 来源:互联网 | 2023-05-17 14:12
标题中的整体缩放指的是,当改变控件大小时,控件带着内部所有视觉元素,作为一个整体缩放,就像变成了它自己的缩略图一样,但缩放后的控件仍然能正常操作;类似于WPF中的Viewbox控件;标题中的界面复
标题中的整体缩放指的是,当改变控件大小时,控件带着内部所有视觉元素,作为一个整体缩放,就像变成了它自己的缩略图一样,但缩放后的控件仍然能正常操作;类似于WPF中的Viewbox控件;
标题中的界面复制指的是,制作一个控件的缩略图,放在另一个图像类控件上显示。当然:1.这个缩略图是实时的;2.整体缩放功能是必须有的;3.就算源控件的一部分或全部因为(被遮挡、不在父容器窗口内、没有设置父容器从而没有加入可视树)等原因不可见,只要该界面本身存在,就存在正常的缩略图。类似于WPF中的VisualBrush类。
Qt中是否内置了提供相应功能的类?没有的话,能否自己方便的实现?
谢谢,因为可用分不多,所以只能在有效答案出来后再加分,望谅解,加分能让您满意的
8 个解决方案
#include
#include
#include
#include
#include
#include
#include
#include
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();
}
#include
#include
#include
#include
#include
#include
#include
#include
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();
}
以上应该是你要的结果。
对应的是第一个问题吗?这个测试代码是如何演示的?我拖拉窗口大小,按钮只是宽度跟着窗口变化,不符合我的要求。我需要的是类似于将鼠标放在Win7任务栏图标上弹出来的缩略图那样,包括控件大小、控件坐标、字体等所有可视元素都被同步缩放的效果
第一个问题,控件中如果没有其他控件,可以重新实现控件的paintEvent事件处理函数,通过setWindow函数和setViewport函数的组合使用来达到整体缩放的效果,这很简单。但是如果控件中还有其他控件,就意味着你需要在resize父控件的同时,重新设置其所有子控件的pos和size,而且子控件的paintEvent事件处理函数也要和父控件一样setWindow和setViewport,那么,你需要在父控件的sizeEvent事件处理函数中告诉其所有子控件重新设置pos和size。这个就麻烦一点,但是应该还是可以实现的。
另外对第一个问题补充一下,如果可能,你也可以不用子控件,而是通过自己画的方式在特定位置画出“子控件”并根据位置等信息让这些“子控件”对事件作出响应,这样你实际上只定义了一个控件,但是这个控件看上去是里面有很多子控件。
第二个问题,用render函数应该可以很轻松的解决。
那就只能重载resizeEvent了,在重载事件里根据父窗口布局大小,来相应缩放子控件的大小
QObjectList *pChildList = this->children();//找到所有的孩子,再判断孩子是否是派生自QWidget,只有这样的孩子,才是窗体,才能对窗体缩放,
可以通过
setGeometry()
resize
等方法实现缩放
如果你要实现鼠标放在控件上,你需要重载,mouse hover事件。
首先,由于你的子widget有字符编辑控件,所以纯自己画的话,确实比较麻烦,但实际上应该还是可以的,不过这个没必要继续深究了。
然后,关于使用setWindow和setViewport之后,字体是否会等比例缩放,是可以等比例缩放的,也可以不等比例缩放,关键在于你是如何设置setWindow和setViewport中对应的区域的高宽比。下一楼的代码中,ScaleWidget的paintEvent函数中,没注释掉的设置是字符会等比缩放的情况,注释掉的设置是字符会被压缩的情况。
最后,关于render,我的代码中,让pShower总是拷贝显示pButtonA上显示的内容,你可以通过点击两个按钮来观看pShower上的显示情况,可以通过pButtonA是否获得焦点来验证pShower上显示的是pButtonA的内容。代码中的两个connect是为了让pShower实时显示pButtonA的内容。
把我下一楼的回复贴到某个cpp文件中,建个空工程,然后跑一下这个cpp文件就可以了。代码写得比较仓促,不严谨的地方不用深究。
#include
#include
#include
#include
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();
}