Is it possible to simply indicate the change of some Qt control's property by changing value of user defined variable (perform an action on changing value). Eg. I declared int a which is frequently used by multiple functions. Now I need to construct a relation: if ( a == 0 ) then my control is inactive else my control is active. (I was inspired by C# data bindings.)
In Qt, controls are enabled/disabled with QWidget::setEnabled. What you'll need to do is create a subclass from which all your gui windows are derived, in which you define a function that sets this variable and calls setEnabled. Like this:
class Widget : public QWidget
{
...
MySetEnabled(bool b)
{
a = b;
setEnabled(b);
}
int a;
};
Signals/Slots
In your accessor methods emit a signal that connect to actions you like to happen.
Related
In gtkmm 4, how can one get the X Window ID of type XID as defined in X11/X.h, from inside a class, that inherits from Gtk::Widget?
Not all of them have one.
Those widgets that do will implement the GtkNative interface, which provides the gtk_native_get_surface function, allowing you to obtain a GdkSurface. In gtkmm, this will correspond to casting to to Gtk::Native and calling get_surface.
To obtain a Window handle from that, you can use the GDK_SURFACE_XID macro. For that, I don’t think a C++ wrapper exists; you will have to call Gdk::Surface::gobj to obtain a GdkSurface * and use the C API.
I wanted to add two things to the accepted answer
It is of course important to check if get_surface() returned a valid nonzero object indeed. Otherwise get the ID after the Widget's signal_realize() is emitted, which is done after the widget is assigned to a surface. This can be achieved by overriding the default handler on_realize()
Instead of casting and calling ((Gtk::Native)this)->get_surface() it is also possible to call like get_native()->get_surface().
In conclusion do
void myWidget::on_realize() {
// Call default handler
Gtk::Widget::on_realize();
XID x_window = GDK_SURFACE_XID(get_native()->get_surface()->gobj());
}
to get the X window ID as early as possible.
I have created a little UI with a simple toolbar. I am initing the toolbar within the initToolbarfunction. This function is within a Class inheriting from QMainWindow.
void Main_Frame::initToolBar() {
rectangle.setText(rectangle_text);
circle.setText(circle_text);
triangle.setText(triangle_text);
triangle.setObjectName(triangle_id);
circle.setObjectName(circle_id);
rectangle.setObjectName(rectangle_id);
toolBar.addAction(&triangle);
toolBar.addAction(&circle);
toolBar.addAction(&rectangle);
connect(
&toolBar, &QToolBar::actionTriggered, this, [=]() {
process_toolbar_ac_evt(*sender());
});
}
I want any tool bar events to be processed through process_toolbar_ac_ect(QObject obj). Within that method, I want to decide what action (within the toolbar) has been triggered.I want to do this by the objectname. Therefore I have given any action an object name. But when I call sender().objectName() I get an empty QString.
My suggestion is, that sender returns a pointer to on of my actions that I put to the toolbar. If this is the case, why I get an empty QString on the sender()?
void Main_Frame::process_toolbar_ac_evt(QObject &evt) {
if (evt.objectName() == circle_id) {
// If circle action has clicked, to this ...
}
}
As you are connecting to one of QToolBar's signals the sender() will be your tool bar object.
Simply use the QAction argument that is passed in the QToolBar::actionTriggered signal. That's what it is for.
NB: Avoid QObject::sender() wherever possible. It virtually breaks the desired decoupling achieved by signals and slots.
I have a couple of widgets in QtCreator that are promoted from the same class. However, I'd like them to have subtle differences between the two, so I'd like to pass some differences in the UI file that the promoted class can use to distinguish itself. Dynamic properties seem like the way to go so in the UI editor I've assigned a dynamic property to each promoted widget. In the code I tried accessing the property, but noticed it seems to only be available post construction (probably because Qt is calling setProperty() after the object is created.
MyWidget::MyWidget(QWidget* parent) : QGLWidget(parent)
{
this->property("someProperty").toString(); // returns blank
}
void MyWidget::initializeGL()
{
this->property("someProperty").toString(); // returns string set in UI file
}
So my question how do people use these properties for constructor-type stuff? I could just do that in initializeGL, but that seems odd since these properties might not be related to initializing OpenGL. I imagine I could also connect to the property changed signal and do it there. Is that the common way to handle this?
If the generated code for setupUi() from your .ui file does something like this:
MyWidget *w = new MyWidget;
w->setProperty(...);
then your constructor is accessing a meta property that does not yet exist.
You can reimplement QObject::event() to capture QDynamicPropertyChangeEvents, letting you act once the property is initialized.
bool MyWidget::event(QEvent *ev)
{
if (ev->type() == QEvent::DynamicPropertyChange) {
if (QDynamicPropertyChangeEvent *propEv = static_cast<QDynamicPropertyChangeEvent *>(ev)) {
if (propEv->propertyName() == "someProperty")
...
}
}
}
Bear in mind that this code will be called every time there is a dynamic property change.
A better approach may be to create a function to perform the necessary initilization on the widget after setupUi() etc. are called and the dynamic property is created.
void setupMyWidget(MyWidget *w)
{
QString s = w->property("someProperty").toString();
...
}
Typically, dynamic properties are assigned a default value in the constructor so that they are always available and non-null later.
setProperty("someProperty", defaultValue);
I have created a simple UserControl consisting solely of a Grid and an embraced Image.
Now I want to apply events such as "ManipulationDeltaEvent", etc. for touch-control. When I assign an event-handler like
pic->ActionToken = pic->ManipulationDelta +=
ref new ManipulationDeltaEventHandler(this, &MainPage::SwipeImageEventHandler);
pic->CompletedToken = pic->ManipulationCompleted +=
ref new ManipulationCompletedEventHandler(this, &MainPage::ImageManipulationCompletedEventHandler);
I receive valid EventRegistrationTokens, but when I want to swipe over the control, simply nothing happens (I debugged).
I read about overriding the OnManipulationDelta-method from Windows::UI::Xaml::Controls::Control, but I here I am stuck:
protected:
void OnManipulationDelta
(Windows::UI::Xaml::Input::ManipulationDeltaRoutedEventArgs^ e) override {
}
Although only barely related, for C++\CLI it states on MSDN:
The OnManipulationDelta method has no default implementation. Override OnManipulationDelta in a derived class to handle the ManipulationDelta event. Be sure to call the OnManipulationDelta method of the base class so that base classes receive the event.
Please give me a hint, thank you.
EDIT
The overriding is unnecessary
You need to specify ManipulationMode on the control and the control needs a non-null Background or Fill, e.g. Background="Transparent".
For example, in an MFC program, I have my main application and a 'class'. What should I do if I want to update a control (say, a listbox) that is situated on my main application from that 'class'?
heres an example that worked for me
theApp.m_pMainWnd->GetDlgItem(IDC_BUTTON6)->SetWindowTextW(L"Run Auto Test");
Your class can be designed to trigger an event which your main application can listen for. Then, a listener/event handler/delegate can be called to handle the event and update the listbox. Typically, most event formats pass a reference of the sender, in this case your 'class', as well as an object containing event arguments. These arguments can be used to pass the list of items you want to add to your listbox.
If you have the handle to dialog object in your class, then you can use GetDlgItem(ResourceID) to get list control object.
The easiest approach is to expose the listview from your application form/window to the classes that use it. You can do this either by passing the listview object (or parent window) to the class constructor, or storing it in a static variable that is accessible by the class.
For better encapsulation, you can put a method in the application that the class can call, e.g. "AddItemToListBox()". This allows the application object to remain in control of how you access the listbox. Again you can do this as a static method, or pass the main program object's 'this' pointer into the class constructor.
i.e.
class CApplication
{
CListBox m_ListBox;
public:
static void CApplication::AddItemToListBox(CString itemText)
{
// Add the item as you wish here
}
}
class CMyClass
{
afx_msg void CMyClass::OnMouseDown(...)
{
CApplication::AddItemToListBox("This is a test");
}
}