QT button becomes unpressable after show() when using OpenCV - c++

I am running QT (5.15.2) on a Raspberry Pi (4B, Raspbian Bullseye 11) and using OpenCV (4.5.1) to do some image processing. I have a main window with 2 buttons in which one starts as greyed out as the first step must be completed before the second. I use the hide() QT function to hide the main window and pop up some gui elements using OpenCV. Once the OpenCV elements are finished and destroyed, I use show() to bring back the main window and ungrey the second button via setEnabled(true). This is where the problem occurs, as but buttons become unpressable on the screen, ie I cannot press the button on the touchscreen I am using.
Through testing I have found that when the loop that controls the OpenCV elements is allowed to end via the time expiring, then the problem does not occur. When the OpenCV elements are manually closed via sliding the "Set" slider from 0 to 1, then the problem occurs. The problem does not occur when using any of the other sliders
The buttons are still active however, as when I plug a keyboard in I can still operate the buttons and the code runs as usual, but I cannot press them using my finger or a mouse. Unfortunately having a keyboard to operate it isn't going to work for my use case.
The code for the loop that controls the OpenCV elements is:
void MainWindow::on_Button1_clicked()
hide();
//Code to load image is here, but is just the basic way of image loading with OpenCV
//Code to create the two OpenCV windows needed inside the loop goes here
time(&iTime);
while(OnOff == 0 && difftime(cTime,iTime) < 5){
createTrackbar(track_val, ControlPanel,&thresh_val,thresh_max_val); //binary gray value
createTrackbar(track_OnOff, ControlPanel,&OnOff,1); //video window on and off
createTrackbar(X_top_left, ControlPanel,&X,638); //bounding box top left X
createTrackbar(Y_top_left, ControlPanel,&Y,478); //bounding box top left Y
createTrackbar(X_size, ControlPanel,&Width,640); //bounding box width
createTrackbar(Y_size, ControlPanel,&Height,480); //bounding box height
createTrackbar(Max_Rad, ControlPanel,&max_rad,max_circ_rad); //Circle Size
imshow(ImageWin, img);
waitKey(1);
time(&cTime);
}
destroyAllWindows();
show();
}
I have uploaded all the code as a minimum reproducible example here.
Thanks for any help.

I was not able to find the cause of the issue however I was able to get around the issue. Using Yunus' advice, I removed the OpenCV gui components.
I used this code to create a method that opened the webcam so I could use OpenCV to process the image in the manner I needed.
So lesson learned, don't mix two different gui generators.

Related

gtk image suddenly do not refresh without any errors or warnings

I develop a tool to capture image from a camera and show the captured image in a window. The GUI window is based on GTK 2.4. At begin, the tool is running correctedly, and the image is captured from camera and showed on the window in real-time. After a while, the image suddenly do not refresh any more on the window, but it's still captured from the camera. There is no errors or warnings. Anyone has ever encountered such a case? Thank you.
Ubuntu 18.04, GTK 2.4
// loop to call the following code to refresh the image on the window
pixbuf_ = Gdk::Pixbuf::create_from_data(
final_img_buf_.data, Gdk::COLORSPACE_RGB, false, 8, final_img_buf_.cols,
final_img_buf_.rows, static_cast<int>(final_img_buf_.step));
gtk_image_.set(pixbuf_);
Edit at 2019-02-27
Thanks for all your replies. I have upgraded GTK to GTK+ 3, but this still appears.
// loop to call the following code to refresh the image on the window
pixbuf_ = Gdk::Pixbuf::create_from_data(
final_img_buf_.data, Gdk::COLORSPACE_RGB, false, 8, final_img_buf_.cols,
final_img_buf_.rows, static_cast<int>(final_img_buf_.step));
// ensure the image is normally updating
//std::this_thread::sleep_for (std::chrono::milliseconds(30));
gtk_image_.set(pixbuf_);
Glib::RefPtr<Gdk::Pixbuf> pixbuf = gtk_image_.get_pixbuf();
std::string filename = std::string("./debug/") + std::to_string(CurTimestampMicrosecond()) + std::string(".jpg");
pixbuf->save(filename, "jpeg");
Afther running a while, the window does not refresh image any more, but the image is still saved correctedly.
Edit at 2019-02-28
// The initialization code
gtk_main_.reset(new Gtk::Main(argc, argv));
ctrl_window_.reset(new CtrlWindow(screen, ctrl_rect)); // inherited from Gtk::Window
thread_ = std::thread([this]() {
Gtk::Main::run(*ctrl_window_);
}
Looks like both g_timeout_add and possibly g_idle_add can be delayed due to the processing of other event sources, so is not optimal in contexts requiring precise timing, like drawing an image to a screen before the frame updates. I've noticed using g_timeout_add in a 2D graphics context completely freezes the application if it can't load a frame at the fps specified.
gtk_widget_add_callback() might be more suited to your needs as it will draw the buffer as quickly as the application can, without hangs, basically doing the messy synchronization for you.

WIndows Flickering when changing focus in OpenGL

I'm working on a project that requires me to switch between two windows, one using OpenCV and one using OpenGL, both fullscreen.
A GLFW key event opens the OpenCV window fine, but closing the OpenCV window, and attempting to return focus to the OpenGL window results in the window flickering and repeatedly attempting to give focus. This is my code to return focus to the OpenGL window, inside a while loop.
Edit: Ive found out that it only happens when the OpenGL window is fullscreen, which is a requirement of this program. Writing to console shows that the code is being called multiple times
if(!glfwGetWindowAttrib(window, GLFW_FOCUSED))
{
glfwFocusWindow(window);
while(!glfwGetWindowAttrib(window, GLFW_FOCUSED))
{
}
}
I managed to fix my problem by setting the GLFW flag GLFW_AUTO_ICONIFY to false on my openGL window.
The way you posted is not the proper way to set focus.
Use glfwSetWindowCloseCallback to set a close callback.
In that callback is where you set focus to another window.

Qt - cross platform behaviour

I am trying to deploy a cross platform Qt application written in c++. It works fine on my Ubuntu Linux but when I run it on Windows the application's main window's position gets set on the very top left point of the screen with the upper frame (that holds the minimize, maximize, close buttons) missing.
That is it until i resize the main window (in this case making the width smaller from the right). When this happens the upper frame and the control buttons appear as in the visualization I provided.
Note: I've removed all widgets on the app so they do not аppear as a distraction.
Note2: It appears the maximize button is disabled, which is not the case inside Ubuntu. I have not set any window flags.
How do i visualize the upper frame at the very start of the application without the need to resize the window. I understand its an OS specific behaviour. Setting the main window's geometry with a starting point with a higher y value does NOT help. It still pops at the very top left of the screen.
try to use QWidget::move to set the Window position after setGeometry.
If the widget is a window, the position is that of the widget on the
desktop, including its frame.
You ask a question about cross-platform UI code, and then you don't show the full code. Please show the full code.
The one line of code you do show does something in the wrong way: if you want to maximize a window, call the appropriate function, instead of setting its absolute size that you think shows the window maximized. Windows, their decorations and their placement are very very platform specific, and you should prefer their cross-platform abstractions over trying to do them yourself.
Concretely: the window positioning handles the decorations (title bar) differently on Windows and on Ubuntu. There is absolutely nothing you can do about it except not position your windows absolutely like this.
In the MainWindow constructor at the end this->setGeometry(0, 0, 1336, 600);
That's the problem. setGeometry deals with the geometry of the client area. This is well documented. You should use move to change the position of the widget frame. To set the size of the frame requires the knowledge of the frame's incremental width and height:
bool setWidgetFrameGeometry(QWidget *w, const QRect &r) {
auto frame = w->frameGeometry().size();
auto client = w->size();
auto delta = frame - client;
auto maxDelta = 128;
if (delta.width() > 0 && delta.width() < maxDelta
&& delta.height() > 0 && delta.height() < maxDelta) {
w->move(r.topLeft());
w->resize(r.size() - delta);
return true;
}
return false;
}
The call may need to be deferred to when the event loop had a chance to run:
auto setter = [this]{ return setWidgetFrameGeometry(this, {0,0,1336,600}); };
if (!setter())
QTimer::singleShot(0, this, setter);

OSG window blocks refresh of OpenCV window

I have an app that shows (processed) webcam output in an OpenCV window (using imshow) and also, in a different thread, has an OSG window showing some geometry. The problem is that as long as the OSG window is refreshing, the OpenCV window does not update (all the processing in the thread happens, just the call to imshow does nothing). If I drag the OSG window, disabling refreshes, the OpenCV window starts updating normally.
Any ideas why this could happen?
(Windows 8, NVIDIA Quattro K2100, VC++)
You need to call the cv::waitKey() function inside the OpenSceneGraph viewer loop to have your OpenCV windows update. This means that you cannot simply use the OpenSceneGraph function viewer.run(). Instead you have to use the following viewer loop:
while (!viewer.done())
{
cv::waitKey(1);
viewer.frame();
}

Cocos2d-x SetFrameSize make screen touch event wrong position

I use visual studio to implement my Win32 game project, but because I will port it to android platform later, so in AppDelegate class, I use setFrameSize to make window screen be like a mobile screen as below:
glview->setFrameSize(600, 900);
glview->setDesignResolutionSize(320, 480, ResolutionPolicy::FIXED_WIDTH);
But I got problem when implementing menu items, if I use setFrameSize function, when I touch to menu item, they does not work because their visual position is diffent from thier real position. If I comment out the set frame size command, menu items work correctly, but my screen too big and is very difficult for me to develope mobile game. Does anyone know why this problem come to me and how to resolve it? Thank alot.
Edit: I use visibleSize to set position for my menu items. It seem to not the same as what I want because when I set position of sprite is 3/8 of screen height ( bottom up), it become 1/2 of screen height ( bottom up).