Click a QPushbutton in a QWidget will cause focusOutEvent, how to ignore this? - qwidget

In my code when focusOutEvent slot calls, this widget will be closed. While, I came cross a problem that click a QPushbutton in this current widget will also cause focusOutEvent and button clicked() signal can never be triggered any more.
In construct function:
connect(btn, SIGNAL(clicked()), this, SLOT(btnClickFucntion()));
then, I have function like following:
void AWidget::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event);
this->close();
}
void AWidget::focusOutEvent(QFocusEvent *event)
{
if (!this->isHidden())
{
event->accept();
this->close();
}
else
event->ignore();
}
void AWidget::btnClickFucntion()
{
//Do something
}
However, btnClickFucntion{} never called.

bool AWidget::isFocusChange2BtnInside()
{
QPushButton *btn = dynamic_cast<QPushButton *>(this->focusWidget());
if (btn == this->btn)
return true;
else
return false;
}
I add this function as a condition(if true, return; else go next step) before calling close() function, and fix it.
Sorry to bother.

Related

How does WorldEdit handle brushes?

I'm trying to find out how the Bukkit version of WorldEdit handles brushes. I've been looking at the source code on GitHub, but I couldn't find anythig useful. I've tried to recreate the effect, but I can only get it to work when I'm in interaction reach of the target block.
This is about as close as it gets in the source code:
} else if (action == Action.RIGHT_CLICK_AIR) {
if (we.handleRightClick(player)) {
event.setCancelled(true);
}
}
(WorldEdit/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java, line 143-147)
There are some other parts of code that get very close. I've also looked in /worldedit-core, but nothing there either.
Could someone help me here?
Edit: This is how I try to do it:
public static void onRightClick (PlayerInteractEvent event) {
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
Location location = event.getClickedBlock().getLocation();
if (event.getItem() != null) {
if (event.getItem().getItemMeta().equals(ItemManager.wand.getItemMeta())) {
Player player = event.getPlayer();
player.getWorld().doStuff(location);
}
}
}
}
Edit #2: what I'm most curious about is: How does WE select the location to apply the brush if you are outside of interaction reach?
I needed to use BlockIterators for this. The final code looks like this:
public class BoomWandEvent implements Listener {
#EventHandler
public static void onRightClick (PlayerInteractEvent event) {
Player player = event.getPlayer();
if (event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.RIGHT_CLICK_AIR) {
if (player.getInventory().getItemInMainHand().equals(ItemManager.explosionWand)) {
Location eyePos = player.getEyeLocation();
BlockIterator raytracer = new BlockIterator(eyePos, 0.0D, player.getClientViewDistance() * 16);
while (raytracer.hasNext()) {
Location location = raytracer.next().getLocation();
if (player.getWorld().getBlockAt(location).getType() != Material.AIR && player.getWorld().getBlockAt(location).getType() != Material.CAVE_AIR && player.getWorld().getBlockAt(location).getType() != Material.VOID_AIR) {
player.getWorld().createExplosion(location, 4f);
return;
}
}
}
}
}
}
Thanks to Rogue for helping!

Catch mouse event on tree widget item in QTreeWidget

In tree widget I have following signal connected:
connect(mTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*, int)),
SLOT(onItemClicked(QTreeWidgetItem*, int)));
where onItemClicked() slot is following:
void WidgetBox::onItemClicked(QTreeWidgetItem *item, int )
{
int index = getPageIndex(item);
setCurrentIndex(index);
}
int WidgetBox::getPageIndex(QTreeWidgetItem *item)
{
if (!item) return -1;
QTreeWidgetItem *parent = item->parent();
if(parent) // Parent is top level item
{
return mTreeWidget->indexOfTopLevelItem(parent);
}
else // Current item is top level
{
return item->treeWidget()->indexOfTopLevelItem(item);
}
}
void WidgetBox::setCurrentIndex(int index)
{
if (index != currentIndex() && checkIndex(index))
{
mTreeWidget->setCurrentItem(mTreeWidget->topLevelItem(index));
emit currentIndexChanged(index);
}
}
However I can't catch itemClicked() signal and onItemClicked() never executed because top level items has push button widget (set with setItemWidget() method) which intercepts mouse event and child items contain container widgets which may have any widget combinations in them.
Is there a good method here to invoke this itemClicked() signal for both top level and child items of tree widget?
installEventFilter() for all widgets found in an item by something like following:QList<QWidget *> widgets = parentWidget.findChildren<QWidget *>();?
Or establish mouse event propagation somehow?
QCoreApplication::postEvent()?
How to organize such process better so all widgets process mouse event as they need to and TreeWidget issue SIGNAL(itemClicked()) as well?
Full sources to reproduce: https://github.com/akontsevich/WidgetBox
So solution is simple and following - just re-send void itemClicked(QTreeWidgetItem *item, int column); signal in PageEventFilter:
PageEventFilter::PageEventFilter(QObject *parent, QTreeWidgetItem *item)
: QObject(parent)
, mItem(item)
{
connect(this, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
mItem->treeWidget(), SIGNAL(itemClicked(QTreeWidgetItem*,int)));
}
bool PageEventFilter::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress)
{
// Resend signal to QTreeWidget
emit itemClicked(mItem, 0);
return false; // Send event to the object (do not filter it)
}
else
{
// standard event processing
return QObject::eventFilter(obj, event);
}
}
P.S. Will leave previous answer as well if somebody needs code or idea.
Created event filter like this:
class PageEventFilter : public QObject
{
Q_OBJECT
public:
PageEventFilter(QObject *parent, QTreeWidgetItem *item);
protected:
bool eventFilter(QObject *obj, QEvent *event);
private:
QTreeWidgetItem *mItem;
};
bool PageEventFilter::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress)
{
// Emitate mouse event for parent QTreeWidget
QMouseEvent *oldEvent = (QMouseEvent *)event;
QRect itemRect = mItem->treeWidget()->visualItemRect(mItem);
QPointF mousePos(itemRect.x() + 1, itemRect.y() + 1);
QMouseEvent *newEvent = new QMouseEvent(oldEvent->type(),
mousePos,
oldEvent->button(),
oldEvent->buttons(),
oldEvent->modifiers());
QCoreApplication::postEvent(mItem->treeWidget(), newEvent);
return false; // Sent event to the object (do not filter it)
}
else
{
// standard event processing
return QObject::eventFilter(obj, event);
}
}
Install it to a button in tree widget item. It creates and sends (imitates) mouse event to tree widget, however tree widget still does not send itemClicked(QTreeWidgetItem*, int) signal. What is the problem could be? Wrong mouse pos? Tried to send event to viewport() - no luck as well. Any way to solve this?

Java: change variable from outside while looping through a while queque

I am a Java Beginner and have a little question.
I have got 2 Classes:
the first one is a java formular, the important code is:
#Override
public void keyPressed(KeyEvent event) {
int key = event.getKeyCode();
if(key == 17) {
System.out.println("STRG");
if(roboter.running == true) {
roboter.running = false;
}
}
}
the second one is a class (called robot) which main part is the for loop:
public class Roboter {
public boolean running = false;
public void myFunction() {
for(...;...;...) {
for(...;...;...) {
if(!running)
break;
// DO SOMETHING IMPORTANT
}
}
}
Well, this doesn't work. I think it is because I can't change the value of running while my for loop. I have no idea how to slove this problem. Maybe there is an other solution? My aim is to stop the robots myFunction if an user press a key.I hope you can help me
I am sorry for my english, if you don't undestand me I will try to rewrite the question.
The class that handles the keyboard input should run in a separate Thread.

Problems with secondary live tile in windows 8

i have a problem with a secondary live tile. I pin it within my application and i want
that it get the user to a deep link, where he pinned it.
In the App.xaml.cs file i add this to the onlaunched event:
if (rootFrame.Content == null)
{
// Wenn der Navigationsstapel nicht wiederhergestellt wird, zur ersten Seite navigieren
// und die neue Seite konfigurieren, indem die erforderlichen Informationen als Navigationsparameter
// übergeben werden
if (!string.IsNullOrEmpty(args.Arguments))
{
rootFrame.Navigate(typeof(qurandb));//, args.Arguments);
}
else
{
// rootFrame.Navigate(typeof(qurandb), args.Arguments);
rootFrame.Navigate(typeof(GroupedItemsPage), "AllGroups");
}
/* if (!rootFrame.Navigate(typeof(GroupedItemsPage), "AllGroups"))
{
throw new Exception("Failed to create initial page");
} */
}
My problem is, that this is only working when the app is launched for the first time. When i click later on the secondary tile (the app is resume), i dont get to the destination i want, but to the point, where i was when i suspended the app.
Can anybody help me with this?
An app's OnLaunched event will be called when the secondary tile is clicked upon. The code you provided assumes that it will only be called when rootFrame.Content is null, and is not navigating to the appropriate page if your app is already running. The code needs to handle the case where the frame content is not null.
if (rootFrame.Content == null)
{
...
} else {
// Need to handle the case where rootFrame.Content is not null
}
You need to handle the OnResuming event as follows:
In your App.xaml.cs
public App()
{
//...
this.Resuming += OnResuming;
//...
}
//...
private void OnResuming(object sender, object e)
{
//there are no args here to access. So need to figure out some way to decide what page to show
bool showShowQuranDb = true; //your logic here
if (shouldShowQuranDb)
{
rootFrame.Navigate(typeof(qurandb));
}
else
{
rootFrame.Navigate(typeof(GroupedItemsPage), "AllGroups");
}
}

Pause application in QML when app is in background Symbian

I want to know of any pure QML way to find out whether the application is in the background or not and then accordingly stop or play music. In meego the alternate way to do is through the PlatformWindow Element but it does not exist in Symbian QML. Help needed please
Finally I got it working :) and i did it though Qt way... here are the steps
1) Create a class MyEventFilter
class myEventFilter : public QObject
{
bool eventFilter(QObject *obj, QEvent *event) {
switch(event->type()) {
case QEvent::WindowActivate:
emit qmlvisiblechange(true);
qDebug() << "Window activated";
bis_foreground=true;
return true;
case QEvent::WindowDeactivate:
emit qmlvisiblechange(false);
qDebug() << "Window deactivated";
bis_foreground=false;
return true;
default:
return false;
}
}
void dosomething();
private:
int something;
public:
bool bis_foreground;
Q_OBJECT
public slots:
Q_INVOKABLE QString checkvisibility() {
if (bis_foreground==true) return "true";
else return "false";
}
signals:
void qmlvisiblechange(bool is_foreground);
};
2) Then in main.cpp include this file include the class and add setContext propery like this
context->setContextProperty("myqmlobject", &ef);
3) in qml file call it like this:
Item {
id: name
Connections
{
target:myqmlobject
onQmlvisiblechange:
{
if(is_foreground)
{
//dont do anything...
}
else
{
playSound.stop()
}
}
}
}
Enjoy :)
Why do you need a pure QML way?
You can detect if an application has been sent to the background by installing an event filter.
Check: http://www.developer.nokia.com/Community/Wiki/Detecting_when_a_Qt_application_has_been_switched_to_the_background_and_when_resumed
For a "pure" QML way, there is the Symbian QML element:
http://doc.qt.nokia.com/qt-components-symbian/qml-symbian.html
It has a foreground property that indicates whether the app is in the foreground or in the background. You can try connecting to onForegroundChanged.
From the documentation, the Symbian element is not "creatable". It exists as a context property named symbian. So a sample usage would be:
import QtQuick 1.1
import com.nokia.symbian 1.1
PageStackWindow {
id: window
initialPage: MainPage {tools: toolBarLayout}
showStatusBar: true
showToolBar: true
function appForegroundChanged() {
console.log("Foreground: " + symbian.foreground)
}
function appCurrentTimeChanged() {
console.log("Current time: " + symbian.currentTime)
}
Component.onCompleted: {
symbian.currentTimeChanged.connect(appCurrentTimeChanged)
symbian.foregroundChanged.connect(appForegroundChanged)
}
ToolBarLayout {
id: toolBarLayout
ToolButton {
flat: true
iconSource: "toolbar-back"
onClicked: window.pageStack.depth <= 1 ? Qt.quit() : window.pageStack.pop()
}
}
}