I am new to QT. I have several QDialogs in my QT project. I have created a generic class to change the properties of widgets inside QDialogs. My generic class has a static method which will change the properties of widgets.
void MyClass::setFontsizeToWidgets(float modValue, QObject obj)
{
QFont f;
float pointSize = 0.0;
QList<QPushButton*> buttons = obj.findChildren<QPushButton*>();
foreach ( QPushButton * button, buttons)
{
f = button->font();
pointSize = f.pointSizeF();
f.setPointSizeF(pointSize*modValue);
button->setFont(f);
}
}
Now my questions is, how to pass the QDialog as a object to the above static method from QDialog class? So that the static method will change the font size of the QPushButton(s) in the QDialog.
You can do it like this:
void MyClass::setFontsizeToWidgets(float modValue, QObject *obj)
{
//do something
}
void MyDialog::someFunction() //this is a function of your QDialog class
{
MyClass::setFontsizeToWidgets(10, this);
}
Related
I have a QHBoxLayout in which I added some widgets. I need to be able to refresh the layout dynamically so I use this to clear the layout :
void ClearLayout(QLayout* layout)
{
if (!layout)
return;
QLayoutItem* item;
while ((item = layout->takeAt(0)) != nullptr)
{
delete item->widget();
ClearLayout(item->layout());
}
}
This indeed removes all widgets and layouts. After this layout->isEmpty() returns true and layout->count() returns 0.
However, when I try to add new widgets (same type of other previously added but new instance) It does not work !
AddWidget()
{
// DeviceWidget inherits QWidget
DeviceWidget* deviceWidget = new DeviceWidget;
deviceWidget->setFixedSize(150, 200);
connect(deviceWidget->GetSignalObject(), &DeviceObject::Selected, this,
&DeviceLayout::SelectedDevice);
layout->addWidget(deviceWidget, 0, Qt::AlignCenter);
}
This is the same function used previously to add the widgets to the layout and worked the first time at Construction:
MainLayout(QWidget* parent) : QHBoxLayout(parent)
{
layout = new QHBoxLayout;
addLayout(layout);
uint32 nb = GetDeviceNumber(); // returns 2
for (uint32 i = 0; i < deviceNb; ++i)
AddDeviceWidget();
}
After trying to add 2 widgets I have layout->isEmpty() returns true and layout->count() returns 2 so I'm confused …
thanks for any help provided :)
EDIT:
The problem seems to be comming from my DeviceWidget class since trying to add a simple QLabel to the cleared layout worked. Here's the DeviceWidget Constructor:
DeviceWidget::DeviceWidget(QWidget* parent) : QWidget(parent)
{
QVBoxLayout* vLayout = new QVBoxLayout;
QLabel* deviceIcon = new QLabel("DeviceIcon", this);
deviceIcon->setFixedSize(128, 128);
deviceIcon->setPixmap(QPixmap::fromImage(QImage("Resources/Icons/device.png")));
deviceIcon->setObjectName("DeviceIcon");
// StatusWidget inherits QWidget
// Just override paintEvent to display a colored filled disk
m_status = new StatusWidget(20, Status::Close, this);
m_status->setObjectName("DeviceStatus");
vLayout->addWidget(deviceIcon, 0, Qt::AlignCenter);
vLayout->addWidget(m_status, 0, Qt::AlignCenter);
// DeviceObjct inherits from QObject an add a signal
m_object = new DeviceObject(size());
// Function clearing the stylesheet background-color
Clear();
setLayout(vLayout);
installEventFilter(this);
setObjectName(QString("DeviceWidget"));
}
Commenting installEventFilter(this) make it work so I think I need to add an event filter to make it work but I don't know which one
As said in the Edit, The problem is coming from DeviceWidget added in the layout that override eventFilter. There is probably a way to add a case in eventFilter to make it work but in my case it was best either (1) or (2):
1. Remove eventFilter from class DeviceWidget and put it in class DeviceObject: m_object is present to emit a signal according to event:
DeviceObject.h:
DeviceObject(QObject* parent);
bool eventFilter(QObject* obj, QEvent* event) override;
signals:
void Select(uint32 i);
Then in class DeviceWidget still call installEventFilter but with m_object as parameter: installEventFilter(m_object);
For the other event (Enter/Leave) I overrode void enterEvent(QEvent* event) and void leaveEvent(QEvent* event) for class DeviceWidget. That's what lead me to the second option that seems better.
2. Completely remove eventFilter and installEventFilter as it is only used to emit a signal when widget is clicked and do things when cursor hovers the widget. Instead override enterEvent and leaveEvent for class DeviceWidget like said before for hover event.
Then in class DeviceObjecy override void mousePressEvent(QMouseEvent*) for clicked event.
I have an one function which is responsible for initializing custom widget and add it in to the MdiArea.When I call this at first time it is working fine.But if i will call again, it is initializing custom widget but not adding in into the MdiArea. I have mentioned that function here:-
void CArbWaveViewWidget::newFile()
{
m_ptrWavePresenter = new CArbWavePresenter;
QMdiSubWindow *subWindow1 = new QMdiSubWindow;
subWindow1->setWidget(m_ptrWavePresenter->getTableView()); // getting customWidget
qDebug()<<"Table View ==="<<m_ptrWavePresenter->getTableView();
subWindow1->setAttribute(Qt::WA_DeleteOnClose);
QMdiSubWindow *subWindow2 = new QMdiSubWindow;
subWindow2->setWidget(m_ptrWavePresenter->getGraphView()); // getting customWidget
qDebug()<<"Graph View ==="<<m_ptrWavePresenter->getGraphView();
subWindow2->setAttribute(Qt::WA_DeleteOnClose);
mdiArea->addSubWindow(subWindow1);
mdiArea->addSubWindow(subWindow2);
}
How can i solve this problem?
1. Declare your QMdiSubWindow
When you declare a QMdiSubWindow, give mdiArea as argument
QMdiSubWindow *subWindow = new QMdiSubWindow(mdiArea);
or you can use setParent ( QWidget * parent )
QMdiSubWindow *subWindow = new QMdiSubWindow();
subWindow->setParent(mdiArea);
2. Create and add your QWidget in your QMdiSubWindow
QWidget *myWidget = new QWidget();
subWindow->setWidget(myWidget);
3. Update QMdiSubWindow content
If you need to update the subwindow content, declare your QMdiSubWindow as class variable, initialize your QMdiArea and QMdiSubWindow and set QWidget
yourClass.h
class yourClass {
public:
yourClass();
void newFile();
private:
QMdiArea *m_area;
QMdiSubWindow *m_subWindow1, *m_subWindow2;
void init();
};
yourClass.cpp
yourClass::yourClass()
{
init();
}
void yourClass::init()
{
m_area = new QMdiArea();
m_subWindow1 = new QMdiSubWindow(m_area);
m_subWindow2 = new QMdiSubWindow(m_area);
// continue to init your QMdiSubWindow
}
void yourClass::newFile()
{
// Set your QWidget (yourWidget) into your QMdiSubWindow
m_subWindow1->setWidget(yourWidget);
m_subWindow2->setWidget(anotherWidget);
}
You need invoke method "show"
QMdiSubWindow *subWindow = new QMdiSubWindow();
subWindow->setParent(mdiArea);
subWindow->setWidget(yourWidget);
subWindow->show();
I tried to animate a tool button using QPropertyAnimation. However, it did nothing. Is there anything I have done wrong? Can anyone please help?
ToolBarPalettes.h:
class ToolBarPalettes : public QToolBar
{
public:
ToolBarPalettes(void);
~ToolBarPalettes(void);
public slots:
void startAnimation();
private:
createButtons();
QToolButton *animatedButton;
}
ToolBarPalettes.cpp:
ToolBarPalettes::ToolBarPalettes(void)
{
createButtons();
connect(animatedButton, SIGNAL(clicked()), this, SLOT(startAnimation()));
}
void ToolBarPalettes::createButtons()
{
animatedButton = new QToolButton;
animatedButton->setText("Animate!");
addWidget(animatedButton);
}
void ToolBarPalettes::startAnimation()
{
QPropertyAnimation *animation = new QPropertyAnimation(animatedButton, "geometry");
animation->setDuration(3000);
animation->setStartValue(QRect(this->x(), this->y(), this->width(), this->height()));
animation->setEndValue(QRect(this->x(), this->y(), 10, 10));
animation->setEasingCurve::OutBounce);
animation->start(QAbstractAnimation::DeleteWhenStopped);
}
You should use the minimumSize, maximumSize or size properties instead of the geometry property.
animation = new QPropertyAnimation(animatedButton, "minimumSize");
then set the values:
animation->setStartValue(animatedButton->minimumSize());
animation->setEndValue(QSize(100,100));
The geometry property only works for top-level windows and widget's that are not contained in a layout.
I created tab with:
ui->tabWidget->addTab(widgetTab,"Title");
I want to add a refresh button after tab text "Title". How can I do that?
I don't believe you can directly. The QTabBar element of QTabWidget is only accessible via the tabBar() member function, which is protected. And QTabBar's setTabButton isn't exposed otherwise in the tab widget's interface.
You could do it by subclassing QTabWidget though. Something like:
class MyTabWidget: public QTabWidget
{
Q_OBJECT
public:
MyTabWidget(QWidget *parent = 0)
: QTabWidget(parent)
{
addTab(new QLabel("foo"), "foo");
addTab(new QLabel("bar"), "bar");
QPushButton *b1 = new QPushButton("<");
QPushButton *b2 = new QPushButton(">");
tabBar()->setTabButton(0, QTabBar::LeftSide, b1);
tabBar()->setTabButton(1, QTabBar::RightSide, b2);
}
};
Why doesn't drag and drop pictures work on this QTextEdit? I have tried everything.
here is the class TextEdit:
//textedit
class TextEdit : public QTextEdit
{
Q_OBJECT
public:
TextEdit(QWidget*parent) : QTextEdit(parent)
{
this->setAcceptDrops(true);
}
virtual void dragEnterEvent(QDragEnterEvent *e)
{
e->accept();
//QTextEdit::dragEnterEvent(e);
}
virtual void dragLeaveEvent(QDragLeaveEvent *e)
{
e->accept();
//QTextEdit::dragLeaveEvent(e);
}
//
virtual void dragMoveEvent(QDragMoveEvent *e)
{
e->accept();
// QTextEdit::dragMoveEvent(e);
}
virtual void dropEvent(QDropEvent *e)
{
QTextEdit::dropEvent(e);
}
bool canInsertFromMimeData(const QMimeData *source ) const
{
if (source->hasImage())
return true;
else
return QTextEdit::canInsertFromMimeData(source);
}
void insertFromMimeData( const QMimeData *source )
{
if (source->hasImage())
{
QImage image = qvariant_cast<QImage>(source->imageData());
QTextCursor cursor = this->textCursor();
QTextDocument *document = this->document();
document->addResource(QTextDocument::ImageResource, QUrl("image"), image);
cursor.insertImage("image");
}
}
};
context context context context context context context context context context context context context context context context context context context context context context context context context context context context context context context context
It depends on what application you are dragging the images from and what data that application decides to include in the operation. If it is not working for you, it is because whatever you are dropping contains no image data and probably only contains a URL or file path.
Dragging images from the file explorer under Windows 7 for me at least does not work but opening an image in the latest version of Firefox and dragging that onto the text edit does work. Try it :)