c – 以编程方式推广QWidget
我在QWidget中有一个带有QProgressBar的ui文件.此外,我已经创建了继承自QProgressBar的自定义进度条组件.在QT Designer中,我可以将QProgressBar小部件提升为我的自定义小部件.有没有办法在widget cpp文件中执行此操作而不是使用QT Designer?
换句话说,有没有办法以编程方式将QWidget推广到另一个相同类型的自定义窗口小部件(一种变形)? 以下是一个例子: class MyProgressBar : public QProgressBar { Q_OBJECT public: explicit CmdProgressWidget(QWidget *parent = 0); ~CmdProgressWidget(); int myCustomFunction(); }; class MyWidgetWithProgress : public QWidget,public Ui::MyWidget { Q_OBJECT public: MyWidgetWithProgress (QWidget *parent = 0) {setupUi(this);} ~MyWidgetWithProgress() {;} inline int callMyCustomFunction() {progressBar->myCustomFunction();} }; 获取代码int callMyCustomFunction()编译的常用方法是在QT Designer中将窗口小部件(QProgressBar)中的进度条提升为我的自定义窗口小部件MyProgressBar. 回到原始问题:有没有办法以编程方式进行(例如在setupUi(this)之后的MyWidgetWithProgress构造函数中;)? 解决方法
一般来说:没有. Qt Designer生成一个Xyz.ui文件,一个对象树和对象属性的简单XML描述. uic代码生成器获取.ui文件并生成ui_Xyz.h.它的成员类型已设置:您无法以编程方式更改它们,就像您无法以编程方式更改任何其他成员的类型一样. 因此,请在Designer中使用正确的对象类型.如果将某些基类型(比如QProgressBar)提升为您自己的派生类型,则setupUi将创建您的类型的实例.因此,整个问题消失了. 但是您不需要使用Designer更改.ui文件.您可以手动更改它以推广您需要的小部件.假设我们从一个包含进度条的简单小部件开始: <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Form</class> <widget class="QWidget" name="Form"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>256</width> <height>40</height> </rect> </property> <layout class="QGridLayout" name="gridLayout"> <item row="0" column="0"> <widget class="QProgressBar" name="placeholder"> <property name="value"> <number>24</number> </property> </widget> </item> </layout> </widget> <resources/> <connections/> </ui> 要更改progressBar项的类型,必须对XML文件进行两处更改.首先,更改项目本身的类型: <widget class="MyProgressBar" name="placeholder"> <property name="value"> <number>24</number> </property> </widget> 然后将您的类型添加到< customwidgets>项目: <customwidgets> <customwidget> <class>MyProgressBar</class> <extends>QProgressBar</extends> <header>myprogressbar.h</header> </customwidget> </customwidgets> 如果您打算实际上有一个不正确的.ui文件,您可以在运行时进行小部件交换. 这有两个主要方面: >你真的需要一个自定义类型吗? 在许多情况下,您可以在不从基本小部件派生的情况下完成所有操作.是否对你有意义很难说:我不明白为什么你不能在.ui文件中使用正确的类型(MyProgressBar). // Would-Be Derived Class class MyProgressBar : public QProgressBar { int m_var; protected: void paintEvent(QPaintEvent * ev) { QProgressBar::paintEvent(event(ev)); // let the base class paint itself QPainter p(this); // do some overpainting,etc. } public: void doSomething() { m_var = 3; } }; // Do the same using the base class instead: void doSomething(QProgressBar * bar) { bar.setProperty("m_var",3); } void paintEvent(QWidget * w,QPaintEvent * ev) { w->event(ev); // let the base class paint itself QPainter p(w); // do some overpainting,etc. } struct Painter : public QObject { bool eventFilter(QObject * obj,QEvent * ev) { if (obj->isWidgetType() && ev->type() == QEvent::Paint) paintEvent(static_cast<QWidget*>(obj),static_cast<QPaintEvent*>(ev)); return QObject::eventFilter(obj,ev); } } QProgressBar bar; bar.installEventFilter(new Painter(&bar)); >做替换. 您需要通过正确类型的指针/引用/值访问窗口小部件.理想情况下,直接按值存储新窗口小部件. class Form : public QWidget,private Ui::Form { MyProgressBar m_bar; ... } 然后,使用正确类型的实例替换其布局中的占位符窗口小部件. void replace(QWidget * & old,QWidget * replacement) { auto layout = old->parent()->layout(); // name the new widget the same replacement->setObjectName(old->objectName()); // swap the widgets and delete the layout item delete layout->replaceWidget(old,replacement); // delete the old widget delete old; // don't leave a dangling pointer old = nullptr; } Form:: Form(QWidget * parent) : QWidget(parent) { setupUi(this); replace(placeholder,&m_bar); // you have to manually connect slots for the m_bar widget } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |