Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

get the last QWidget actived



  • Hi,

    I'm searching for a function who can give me the last widget activated.

    I call a widget activated a widget who has focus with the mouse, tab, or keyboard.
    For beginning, just with the mouse. A little example :
    0_1537285354050_presentationNucleusCreator.PNG
    In both squares, I have a QTabWidget who contain two tabs.
    In my class, I have a variable "currentLayout" and a static accessor for this variable. In this same class, I want to have a function, that change, when is necessary, the variable "currentLayout".

    I have already try focusInEvent and mousePressEvent but with these functions, they are called when I pressed a button of my mouse inside the square, but outdoor the content of the tab. If I press my mouse in the middle of the square, the function is not called.
    There is a solution?



  • @mrjj
    Hi yes but I have some problems with qobject_cast :
    "Error C2338 qobject_cast requires the type to have a Q_OBJECT macro"
    But in my class, I have the macro :

    class ProjectManager : public QObject
    {
    	Q_OBJECT
    
    public:
    	// Some function...
    	template <class T>
    	T findParent(QObject *child)
    	{
    		T r = nullptr;
    
    		if (!child)
    			return nullptr;
    		QObject *parent = child->parent();
    
    		while (parent) {
    			r = qobject_cast<T>(parent);
    			if (r)
    				return r;
    			parent = parent->parent();
    		}
    		return r;
    	}
    };
    

  • Lifetime Qt Champion

    Hi,

    Would QApplication::focusWidget be what you are looking for ?



  • I thinks it's the same, I remembre when I used it before, and it has same problem : i have to press the mouse outside its content :/



  • I found this signal : QApplication::focusChanged(QWidget *old, QWidget *new)
    And it's work for what I want to do.
    But, this function sends me the most little child of all my widgets. So I have implemented this function :

    template <class T>T findParent(QObject *child)
    {
    	T r = 0;
    
    	if (!child)
    		return nullptr;
    	QObject *parent = child->parent();
    	
    	while (parent) {
    		r = dynamic_cast<T> (parent);
    		if (r)
    			return r;
    		parent = parent->parent();
    	}
    	return r;
    }
    

    And it's working with "findParent<LayoutPanelTabber *>(new);"
    Thanks


  • Lifetime Qt Champion

    @bozo6919
    Hi
    Should dynamic_cast not be qobject_cast ?



  • @mrjj
    Hi yes but I have some problems with qobject_cast :
    "Error C2338 qobject_cast requires the type to have a Q_OBJECT macro"
    But in my class, I have the macro :

    class ProjectManager : public QObject
    {
    	Q_OBJECT
    
    public:
    	// Some function...
    	template <class T>
    	T findParent(QObject *child)
    	{
    		T r = nullptr;
    
    		if (!child)
    			return nullptr;
    		QObject *parent = child->parent();
    
    		while (parent) {
    			r = qobject_cast<T>(parent);
    			if (r)
    				return r;
    			parent = parent->parent();
    		}
    		return r;
    	}
    };
    


  • @bozo6919
    I don't know what the answer is and I don't do C++, but

    r = qobject_cast<T>(parent);
    "Error C2338 qobject_cast requires the type to have a Q_OBJECT macro"

    This will be complaining about the Q_OBJECT on parent or on type T (not sure which, perhaps the latter) not on your class, won't it?


  • Lifetime Qt Champion

    @bozo6919
    Hi
    Ah maybe it don't like templates as T don't exist yet.
    So if static check, there is no way for it to know if contains Q_OBJECT
    or not.



  • @mrjj said in get the last QWidget actived:

    Ah maybe it don't like templates as T don't exist yet.

    That's what I was wondering/suspecting....



  • Yes, it's what I was suspecting too, but in my class, if I call qobject_cast with T = ContentPanelEditor *, who is contained in the same project and have the macro Q_OBJECT, I have the same error...

    Edit:
    No, I misread. ^^' after the qobject_cast on my ContentPanelEditor, I have another cast for a class in another project. So he doesn't know about this class.
    This other class is contained in a dll. There is a way to apply qobject_cast on it?


  • Lifetime Qt Champion

    Hi,

    Can you give more details about that chain of casts ?



  • Hi,

    My program has two projects :

    • one is a DLL.
    • the other an EXE.
      In my EXE, I have to apply a qobject_cast on a class who is contained in my DLL.
      But if I put in this class (in the DLL) the macro Q_OBJECT, my IDE (visual studio 2017) cannot compile the project with an error of linking.

  • Lifetime Qt Champion

    Is your .dll project also managed with Qt ?



  • Yes, theses projects was made with Qt


  • Lifetime Qt Champion

    Then there should be no problem with qobject_cast.



  • Yes, but I have problems, and I don't know yet how to resolve them


  • Lifetime Qt Champion

    What exact problems ?



  • Hi, sorry for my late

    This problem for example :

    #pragma once
    
    #include <QtCore/qobject.h>
    
    class __declspec(dllexport) LayoutManager : public QObject
    {
    	Q_OBJECT
    
    public:
    	template <class T>T findParent(QObject *child)
    	{
    		T r = nullptr;
    
    		if (!child)
    			return nullptr;
    		QObject *parent = child->parent();
    
    		while (parent) {
    			r = qobject_cast<T>(parent);
    			if (r)
    				return r;
    			parent = parent->parent();
    		}
    		return r;
    	}
    };
    

    And I have this error message :
    Error : C2338 : qobject_cast requires the type to have a Q_OBJECT macro

    But the macro is here. So instead of qobject_cast, I have to use dynamic_cast


  • Lifetime Qt Champion

    What type are you looking for ?



  • This is a type who doesn't exist in this project. I use this function in another project


  • Lifetime Qt Champion

    And is that type a QObject based class with Q_OBJECT in it's declaration ?

    @bozo6919 said in get the last QWidget actived:

    class __declspec(dllexport) LayoutManager : public QObject

    On a side note, Qt provides macros to properly handle the export/import stuff. See here.


Log in to reply