capture delete key in CListCtrl and do soem processing - visual-c++

I have a class which inherits from CListCtrl class, say class list.
I have another class dlg, which inherits from CDialog.
Class dlg contains an instance of class list.
I have got a delete button in class dlg, on which I delete the selected item in listCtrl and do lots of other processing.
I want the same functionality on delete key.
I added OnKeyDown() fn is my class list, where I can capture VK_DELETE key. But my problem is that, how do I do otehr processing that I need to do in dialog class.
All that processing is dlg class based not list class based.
I have many such dlg classes with different data and in every dlg class processing is different.
I tried capturing VK_DELETE in dialog class, but it doesn't capture it if focus is on list class.
I am totally stuck and have no idea, how to do this.
Please give me some idea how i can do this.
Thanks,
SG

What about delegating the call captured in the List class to the parent Dialog class. Thus you capture the VK_DELETE on the List class and say to the parent that you received a Delete command. Thus you can keep all your processing on the parent Dialog class if you wish.
((CMyParentDialog*) GetParent())->OnDeleteKeyPressed(this);
Or better, create a custom message and post it to the parent window.
#define W_DELETE_PRESSED_ON_LIST (WM_USER + 1)
GetParent()->PostMessage(WM_DELETE_PRESSED_ON_LIST);

Related

Clean way to get mousePressed event notified to QGraphicsView

I inherited from QGraphicsItemGroup and made a class that keeps a pointer to its contained items so that I can later refer to them and change properties. It has an ellipse item and a line item and I want only the ellipse to be clickable. I need that press event of the ellipse to propagate to the QGraphicsView so that I can send a signal to some surrounding widgets.
So far I tried inheriting also from QGraphicsObject to have signals available but got stuck with ambigous base error when trying to use scene->addItem. I tried casting to QGraphicsItemGroup but I still get the error. I also tried inheriting from QObject with no success.
I'm new to QGraphics and I know the QGraphics framework has a lot of tools for user interaction and even interaction between GraphicsItems but this is really kicking my butt.
What would be the proper way to get this behavior?
Create a separate "emitter" class
To allow your subclass of QGraphicsItemGroup to emit signals, you can create a separate "emitter" class that inherits from QObject. Then, you can add an instance of this emitter class within your subclass of QGraphicsItemGroup. The emitter object can then emit signals for your subclass as needed.
QGraphicsItemGroup is treated as a single item
Unfortunately, an instance of QGraphicsItemGroup is treated as a single item, so each mousePressEvent will belong to the entire group rather than one of the members of that group (i.e., the ellipse item or the line item). If you want the mousePressEvent to behave differently depending on which item is clicked, they will need to be separate items, or you could try using line->setParentItem(ellipse) to link up the 2 items without using QGraphicsItemGroup.

How to get list of widgets in pyqt?

I am designing a interface with QtDesigner and editing its functionalities with PyQt. One of the widgets that i created has several pushButtons and i want them all to have the property Checkable = True.
So currently what i am doing is:
class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__()
uic.loadUi('./my_widget.ui', self)
self.pushButton_X.setCheckable(True)
self.pushButton_Y.setCheckable(True)
self.pushButton_Z.setCheckable(True)
self.pushButton_ETC.setCheckable(True)
self.show()
Is there any way i can do something like:
pushbuttons_list = self.get_all_pushbuttons()
for i in pushbuttons_list:
i.setCheckable(True)
?
Im trying the answers to this question but i keep getting
> File "./testing_class.py", line 12, in __init__
items = (self.layout.itemAt(i) for i in range(self.layout.count()))
AttributeError: 'builtin_function_or_method' object has no attribute 'count'
Your example failed because all Qt properties can be accessed by calling the attribute (see the parentheses used for self.layout()):
items = (self.layout().itemAt(i) for i in range(self.layout().count()))
Note that this will only get access to the layout items, not the widgets they might (or might not) contain. For this, using comprehensions will only complicate things unnecessarily, as one-liners should be used only as long as they keep the code readable; the comprehension above is already complex enough, and since you will need to cycle through all items anyway, there's little use in it. Just use a for loop, which is far more readable:
for i in range(self.layout().count()):
widget = self.layout().itemAt(i).widget()
if isinstance(widget, QPushButton):
widget.setCheckable(True)
Note that if you have several buttons that you want checkable and you are doing this only to avoid manually setting the checkable property for all of them, you can just use the extended selection mode that is common for all UI elements that allow selection by keeping pressed Ctrl when clicking multiple objects.
The property editor will automatically show all common properties for the selected widgets, and apply the changed property to all of them.
Another option is to use findChildren():
for button in self.findChildren(QPushButton, Qt.FindDirectChildrenOnly):
button.setCheckable(True)
The Qt.FindDirectChildrenOnly flag is required whenever you have complex layouts that have nested widgets containing other buttons, if you remove that you will find any push button that exists inside the window (or the widget referenced as self).
Finally, buttons can be part of a QButtonGroup, which can also be created in Designer. Just select all buttons (as explained above), right click on one of them and select "Assign to button group", and then:
for button in self.buttonGroup.buttons():
button.setCheckable(True)
Note that the self.buttonGroup above is the object name assigned by Designer, if you change it or you create more than one, ensure that the reference matches it.

Get all the classes that extend a main class

So, if I had something like
class Event {// . . .}
class Children extends Event {// . . .}
class Second extends Event {// . . .}
Would there be any way to retrieve the Children and Second class objects, using the the parent class Event?
Would there be any way to retrieve the Children and Second class objects, using the parent class Event?
No. Given just the code you show, there would not be any way to identify all subclasses of Event in plain Javascript. A parent object is not informed in any way when a subclass is defined, nor is any global catalog maintained. A subclass definition stands on its own and the fact that it subclasses/extends the Event class is not saved anywhere or registered anywhere. It's just information that is used when an instance of the subclass is actually created.
If you wanted to manually keep track of such a thing, you could create your own catalog of sub-classes and then make your code register everything in that catalog.

How to add logic to QListWidget drag/drop

I'm a Python/PyQt (v4) newbie who is subclassing the QListWidget and making use of its internal drag and drop mechanism:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class AlgorithmListControl(QListWidget):
def __init__(self, parent = None):
super(AlgorithmListControl, self).__init__(parent)
self.setAcceptDrops(True)
self.setDragEnabled(True)
self.setDragDropMode(QAbstractItemView.InternalMove)
I'm happy with the default behavior and appearance and I'm able to drag/drop items internally in the widget. Now, I'd like to add some custom logic that occurs when the drag operation begins and after the drop operation ends. The trouble I'm having is if I handle the events, for example the dragEnterEvent as follows:
def dragEnterEvent(self, event):
...
then I no longer get the nice default drag/drop behavior (I'm unable to drag an item to a new location, I don't get the horizontal insertion indicator, etc). How do I retain the standard drag-drop behavior but add my custom logic at these two event points? Thank you in advance.
Since you override the method when you use the same name, you need to implement all the actions that happen in the standard way, or call the parent (standard) method inside.
You can call the method from the parent class with inheritance, thanks to the function super()and then implement your own logic :
def dragEnterEvent(self, event):
super().dragEnterEvent(event)
print('enter')

PyQt: how to create a dialog as a child of another dialog

In PyQt, I have a dialog that spawns another dialog (when you click a button to do so in the first dialog). I want to maintain a strong parent-child relationship, for garbage collection purposes, and to make the .findChild and .findChildren functions usable.
The root of the question may be: how do you use .setParent() but still have the object in question be shown as a separate window, rather than shown within the parent widget?
The 'parent' dialog (actually a container widget within a tab within a dialog) is 'newEntryWidget'. It spawns 'clueDialog' when a signal (not shown here) calls newEntryWidget.quickTextClueAction as a slot. Visually, clueDialog should be a "top level window" with its own banner, its own window attributes (I want to keep it on top of everything else), etc.
class newEntryWidget(QWidget,Ui_newEntryWidget):
def __init__(self,parent,sec=0,formattedLocString='',fleet='',dev='',origLocString='',amendFlag=False,amendRow=None):
QDialog.__init__(self)
self.parent=parent # just an attribute; not the same as setParent
...
...
def quickTextClueAction(self):
self.newClueDialog=clueDialog(self,self.ui.timeField.text(),self.ui.teamField.text(),self.ui.radioLocField.text(),lastClueNumber+1)
self.newClueDialog.show()
class clueDialog(QDialog,Ui_clueDialog):
def __init__(self,parent,t,callsign,radioLoc,newClueNumber):
QDialog.__init__(self)
self.parent=parent # just an attribute; not the same as setParent
...
...
Right now, since I am using self.parent=parent, which is just an attribute and not true "parent/child relationship" in Qt terms, clueDialog does display as a top level window, which is what I want:
But, if I add 'self.setParent(parent)' in the clueDialog init function, I get this:
How can I preserve the top-level-window behavior, and have the real-honest-parent-child-relationship so that .findChild(clueDialog) will work from within the newEntryWidget object?
Ultimately, I want to enforce that the newEntryWidget object should not be closed if it still has and 'child' clueDialogs open.
Instead of calling .setParent, call QDialog.__init__(self, parent) which constructs the clue dialog with a parent from the beginning. Setting it this way allows Qt establishes the parent-child relationship at the beginning of clueDialog's lifetime.
I believe this will fix both your issues: 1) the clue window frame, caption, etc. will be painted, 2) you will be able to iterate for proper children of newEntry.

Resources