QComboBox has unrelated behavior with QMessageBox - c++11

On a user interface it is possible to upload images on a QGraphicScene using a QPushButton. Additionally on the same interface I have a QCombobox that is doing some operations on the images once they are uploaded. I am setting the user interface so that if I try to use the combobox before any image is uploaded, a QMessage warning pops up telling the user to upload images. It almost works, the issue is that it resets the QCombobox but asks again to upload images. I think it is entering two times in the cycle and I have been struggling in correcting the error.
To recap: I open the interface, try to use the ComboBox; there are no images uploaded and the QMessageBox pops up telling the user to upload images; the Combobox autoresets on the initial value [which in my case is called "Chose operations"] but now another QMessageBox pops up asking the same instead of one time only.
Below the part of the code I think it causing this:
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->leftPreview->setText("<b>No Image Set!</b>");
points.clear();
currentSelection = -1; // used to detect if images have been uploaded on QListWidget
}
void MainWindow::on_primarySubComboBoxLeft_currentIndexChanged(const QString &arg1)
{
if(currentSelection < 0) {
QMessageBox::information(this, "Option not allowed yet", "Please upload images before using this selection");
ui->primarySubComboBoxLeft->setCurrentText("Primary Substrate");
return;
} else {
selections[currentSelection]->setPrimarySubText(arg1);
selections[currentSelection]->updateLabelText();
}
}
mainwindow.h
private:
Ui::MainWindow *ui;
MGraphicsScene* leftScene;
QList<DataRegion*> selections;
int currentSelection;
I think it is entering in the loop twice but I am not sure how to solve this issue. Thanks for any advice.

ui->primarySubComboBoxLeft->setCurrentText(...) changes the current index, which in turn triggers currentIndexChanged signal again. You may want to handle activated signal instead - it only fires when the selection changes via user action, but not when it is changed programmatically.

Related

Blackberry 10 click event not trigger when one screen launch on top of other

FirstScreen.hpp
FirstScreen.cpp
void FirstScreen:: launchSecondScreen(){
SecondScreen secondScreen;
}
firstscreen.qml
Page {
Container {
Button {
onClicked: {
//Launch second screen
console.log("This will print")
_app.launchSecondScreen();
}
}
}
}
SecondScreen.hpp
SecondScreen.cpp
void SecondScreen:: launchThirdScreen(){
ThirdScreen thirdScreen;
}
secondscreen.qml
Page {
Container {
Button {
onClicked: {
//Launch third screen
console.log("This will not print")
_app.launchThirdScreen();
}
}
}
}
What happen once I launch second screen on top of first one click event not trigger. Please go through the link for complete project https://github.com/amityadav1984/BB10MultiscreenIssue
Because of that I have to use NavigationPane.
Thanks for providing a Minimal, Complete, and Verifiable example, it really helps to get all the information needed in order to test and replicate.
First off, let me explain what's happening and then I'll explain how to fix it.
The reason it's not working :
You're creating Screen2 object in a method, the object will be deleted at the end of the method. So basically, you're on Screen1, you click on the button which triggers your launchScreen2 method, this method creates a Screen2 object that sets the new visual to Screen2.qml and then the method delete Screen2 object before exiting. When you click on the button on Screen2.qml page, the _app context doesn't exists anymore.
Why is it working with Screen1 in main.cpp then? Because main.cpp will enter the main event loop before the end of the method, so Screen1 will not be deleted until the main event loop finishes (app exit).
How to fix :
1) Create Screen2 as a pointer :
Screen2* screen2 = new Screen2();
While this will work, be aware that you're responsible for deleting the object when you're done with it, otherwise you'll have memory leaks. A good practice is also to set parent whenever possible, that way you're sure that if the parent is deleted, all children will be too.
screen2->setParent(this);
Of course, while setting parent is a good practice, an even better practice is to delete any object as soon as they are not needed anymore, keeping your memory footprint as low as possible.
2) Declare Screen2 as private variable in Screen1.hpp, to make it a global variable.
Note that by doing so, you need to move the code in Screen2 constructor inside a public method that you'll have to call in Screen1::launchScreen2(), something like screen2.setScene().
Let me know if you need more information.

p5.js global and instance mode confusion

I have two p5 sketches, and I want to use them in the same space of a website. So that after clicking a button, the sketches switch. So I made three different files. The first two, are the sketches, and they are wrapped in a function (instance mode). The third sketch is a code written in global mode, because It has the information that loads a button right when the website is first accesed, and it has the information containing what the button is supposed to do: call the other sketches.
The code looks like this:
var playing = false;
var button;
function setup() {
var col = color(185,185,185,150);
button = createButton('Play');
button.position(20,20);
button.parent('black');
button.style("background-color", col);
button.style("padding", "10px 20px");
button.style("font-size", "14px");
button.mousePressed(toggleCanvas); // attach button listener
}
function mousePressed() {
}
function toggleCanvas() {
if (playing) {
if(myp5r){
myp5r.remove();
runSketch();
button.html('Stop');
}else{
runSketch();
button.html('Stop');
}
}else {
if(myp5){myp5.remove();
stopSketch();
button.html('Play');
}else{
stopSketch();
button.html('Play');}
}
playing = !playing;
}
I have been warned, to not mix global and instance mode, although my "common sense" says that it is ok to use a global mode for the button. Because I want it to be loading first, along with the page.
I noticed that weird things happen, though. Like, I get a blank space added beneath the footer, it looks horrible. And, even more worse, button is not appearing in the correct spot in the site. I already ckecked that css has position:relative for example. And the design works in localhost, but not in the site.

Loading Profile Images on VK.com in ActionScript

I have an iframe application in vk.com. I can use their API everything looks fine but when I want to load profile images I get Security Sandbox Error. When I print the result and errors I get This: (I am using Greensock ImageLoader)
MYURL : 'MY Image URL on cs408919 subdomain of vk'
Loading CrossDomain on cs408919
ScriptAccessDenied : Error #2048
SecurityError : Error #2048
Error : Error #2048
ScriptAccessDenied : Error #2123 Security SandBox Violation, No Policy Files Granted Access
It seems to me crossdomain.xml issue but I couldn't find right one. Thanks...
In additional to fsbmain's answer I want say you have to add following code:
Security.allowDomain("*");
Yes, it's crossdomain issue, vk sub-domains for images doesn't provide crossdomain.xml for user avatars, but you still able to load (and add to display list as well) them. What you can't do is to access the loaded content (and set smooth bitmap flag for example, or draw the hole stage with vk images on it).
If you need the access the content you can use this "policy-hack", but it's hack, so it can be fixed in any FP update (I guess even this answer may bring closer this moment:) ):
The idea is to listen the ADDED event if image Loader:
protected var _prepareloaderBitmap:Bitmap;
_prepareloader.addEventListener(Event.ADDED, onPrepareLoader);
_prepareloader.contentLoaderInfo.addEventListener(Event.COMPLETE, onPrepareLoader);
And the listener:
protected function onPrepareLoader(event:Event):void
{
//event ADDED fired only for Bitmap (not for SWFs)
if(event.type == Event.ADDED)
{
_prepareloaderBitmap = event.target as Bitmap;
}
else if (event.type == Event.COMPLETE)
{
if(_prepareloaderBitmap)
{
trace("loaded image size:", _prepareloaderBitmap.width, "x", _prepareloaderBitmap.height);
}
}
}
Having the reference to the loaded Bitmap you can now add it instead of crossdomain issued loader.

Air HTML Component and HTML_RENDER event

We are currently using the mx:HTML component to render complex HTML pages (which was pretty disturbing..:)). For some reasons, we need, when the HTML is rendered, to capture an image of the displayed page. So i use the following code to do this :
on initialization :
frameHtml.addEventListener(Event.HTML_RENDER, cacheFrameHTML);
and the cacheFrameHTML function :
private function cacheFrameHTML(event:*):void {
...
cacheImage.source = new Bitmap( ImageSnapshot.captureBitmapData(frameHtml));
...
}
For some unknown reason, the result image is sometime completly blank. It seems that there is a short delay between HTML_RENDER event and effective rendering of the HTML component. I tried to delay the image capture with a timer which seems to work, but that is not pretty clean.
So my question is :
- is there anyone who know a trick to only trigger the capture when the HTML frame is effectivly displayed?
- at least, is there anyway to test if the result BitmapData is blank or have only white pixels?:b
Thanks a lot
Antoine
Have you tried to use the callLater method?
The callLater() method queues an operation to be performed for the next screen refresh, rather than in the current update
private function cacheFrameHTML(event:*):void {
...
callLater(saveImage);
...
}
private function saveImage():void
{
cacheImage.source = new Bitmap( ImageSnapshot.captureBitmapData(frameHtml));
}

How could I use the QColorDialog inside another widget not as a separate dialog?

I would like to use QColorDialog not as a dialog window but as a widget which I could insert into a layout. (More specifically as a custom sub menu in a context menu)
I looked into the QColorDialog sourcecode, and I could probably copy over a part of the internal implementation of the QColorDialog to achieve this, but is there a cleaner way to do this? I am using Qt 4.5.1...
QColorDialog is a dialog which means IT IS a widget. All you need to do is set a few window flags and drop it into your layout as you wish. Here is a (tested) example:
#include <QApplication>
#include <QMainWindow>
#include <QColorDialog>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
/* setup a quick and dirty window */
QMainWindow app;
app.setGeometry(250, 250, 600, 400);
QColorDialog *colorDialog = new QColorDialog(&app);
/* set it as our widiget, you can add it to a layout or something */
app.setCentralWidget(colorDialog);
/* define it as a Qt::Widget (SubWindow would also work) instead of a dialog */
colorDialog->setWindowFlags(Qt::Widget);
/* a few options that we must set for it to work nicely */
colorDialog->setOptions(
/* do not use native dialog */
QColorDialog::DontUseNativeDialog
/* you don't need to set it, but if you don't set this
the "OK" and "Cancel" buttons will show up, I don't
think you'd want that. */
| QColorDialog::NoButtons
);
app.show();
return a.exec();
}
You can do it clean in a very simple way by setting right window flags.
QColorDialog8 colorDialog = new ....
colorDialog->setWindowFlags(Qt::SubWindow);
You might want to look at some Qt Solutions, which will do at least part of what you want. For example, see the Color Picker solution, which they note is now available as an LGPL-licensed library also.
As an alternative (and probably less-supported) approach, I recall some work in the Qt-Labs about embedding Qt widgets, including QDialogs, into a QGraphicsScene. You could potentially do so, then change the view on your graphics scene so that only the portion of the color picker dialog you are interested in was visible to the user. It sounds very hackish, however.
Try subclassing QColorDialog
Use QGraphicsView and add QDialog to it. And add QGraphicsView to the widget if you want to show the dialog.
Building on #Wiz's answer, I made mine a popup menu off of a toolbar button using some C++11 features (lambdas and auto; works with VS2010 and gcc 4.6 with Qt 5.1.1):
auto dialog = new QColorDialog();
dialog->setWindowFlags( Qt::Widget );
dialog->setOptions( QColorDialog::DontUseNativeDialog | QColorDialog::ShowAlphaChannel );
auto action = new QWidgetAction( 0 );
action->setDefaultWidget( dialog );
auto menu = new QMenu();
menu->addAction( action );
// The dialog-as-widget closes on Ok/cancel, but the menu that holds it
// doesn't. We connect the two here. Because the dialog hides itself,
// we need to reshow it when the menu is coming up again.
connect( menu, &QMenu::aboutToShow, [=] { dialog->show(); } );
connect( dialog, &QColorDialog::rejected, [=] { menu->hide(); } );
connect( dialog, &QColorDialog::colorSelected,
[=]( const QColor& color )
{
menu->hide();
OnFillColorChanged( color ); // Call the "slot" in this class
});
auto button = new QToolButton();
button->setIcon( QIcon( ":/images/whatev.png") );
button->setText( tr("Fill") );
button->setStatusTip( tr("Choose fill color") );
button->setMenu( menu );
button->setPopupMode( QToolButton::InstantPopup );
button->setToolButtonStyle( Qt::ToolButtonTextUnderIcon );
toolbar->addWidget( button ); // toolbar is defined elsewhere
Base on previous answer from "metal" i suggest you to create the following method in a derived class of QAction:
void MyQAction::setPopupDialog(QDialog* dialog) {
QWidgetAction* action = new QWidgetAction(NULL);
action->setDefaultWidget(dialog);
QMenu* menu = new QMenu();
menu->addAction(action);
// Fix issues related to the way the dialogbox hide/show. Restablish proper handling,
// based on our requirement.
connect(menu, SIGNAL(aboutToShow()), dialog, SLOT(show()));
connect(dialog, SIGNAL(finished(int)), menu, SLOT(hide()));
setMenu(menu);
}
this will automate the process for any dialog box.
If there's a way to do this cleanly, I'm not aware of it. As I see it, you have a couple of options:
Subclass it and copy the code that actually constructs the widget, making edits to remove the part that creates the dialog window and replace it with some other container.
If you're not dead-set on using that particular dialog, the color triangle widget from qt solutions might work, because it isn't a dialog window. You can find it at http:// doc.trolltech.com/solutions/4/qtcolortriangle/qtcolortriangle.html (remove the space from the link)

Resources