PDA

View Full Version : Qcombobox



arturs
26th May 2015, 19:09
Hi

I have QCombox without items. After clicking on the combobox I would like to showmessage but I cannot find slot "Clicked" or something similar.

How to do it ?

Regards
Artur

wysota
26th May 2015, 19:49
There is no such signal. If you want to have one, subclass, reimplement mouse events and emit such signal yourself.

chris.kzn
27th May 2015, 14:36
... in short, add a pushButton, eish, that is just mean - lol.

Radek
27th May 2015, 15:40
No. Do as Wysota has said. The mouse event will hook clicking the combo box and emit a "clicked" signal - perhaps only sometimes (when the combo box is empty). If the combo box isn't empty, you get a signal from the clicked item.

arturs
27th May 2015, 17:33
If it is not problem please give me an example.

Thank you for help

wysota
27th May 2015, 18:07
If it is not problem please give me an example.

An example of what?

arturs
27th May 2015, 18:12
How to do it using QMouseEvent.
How to determine that the left button of mouse was clicked on the Combobox.

wysota
27th May 2015, 18:13
How to do it using QMouseEvent.
How to determine that the left button of mouse was clicked on the Combobox.


void Combo::mousePressEvent(QMouseEvent *e) {
if(e->button() == Qt::LeftMouseButton) emit clicked();
}

arturs
27th May 2015, 20:32
My Code



void Test::mouseMoveEvent(QMouseEvent *event)
{
if (event->button()==Qt::LeftButton) emit clicked();

}

Should I create clicked signal ? because Now I have the following error: 'clicked' was not declared in this scope

wysota
27th May 2015, 20:56
Should I create clicked signal ?

If you want to emit a signal, the signal has to exist. So yes, you need to declare the signal in your class.

arturs
27th May 2015, 21:11
but It is still not clear for me. The signal will be sent each time when the left button of mouse is clicked even if the pointer of mouse there is out of Combobox area.

Second question:
Is it possible to check using a method if a slot was called by signal or was called another method

for example:


I have a slot


void Test:: test1 (void) {

qDebug () << "TEST";
}

I can call it using the following code:
test();

or it can be called by signal.

I would like to know which method was used to call the slot.

wysota
27th May 2015, 21:24
but It is still not clear for me. The signal will be sent each time when the left button of mouse is clicked even if the pointer of mouse there is out of Combobox area.
No. A widget receives mouse events only when they happen over its area.


Is it possible to check using a method if a slot was called by signal or was called another method
QObject::sender()


I would like to know which method was used to call the slot.
What for?

arturs
28th May 2015, 17:50
As I thought It did not work :) something is wrong :)

My code:



#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMouseEvent>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QObject::connect(ui->comboBox,SIGNAL(clicked()),this,SLOT(test()));
}

MainWindow::~MainWindow()
{
delete ui;
}


void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if (event->button()==Qt::LeftButton) emit clicked();

}


void MainWindow::test (void){

qDebug () << "TEST SIGNAL";


}




#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void mouseMoveEvent(QMouseEvent *);
void test (void);
signals:
void clicked(void);

private:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H








No. A widget receives mouse events only when they happen over its area.


QObject::sender()


What for?


I have a method open_file and in the first case I choose proper file from C: disk (QfileDialog) in second case the same file is downloaded from server and write for example on C: disk.
In second case I know file path so I do not know to choose file once again but used path which was chosen before writing file.

How to skip the part of code which open Qfiledialog.

Regards
Artur

wysota
28th May 2015, 20:34
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if (event->button()==Qt::LeftButton) emit clicked();

}
First of all this is a handler for mouseMoveEvent for which button() always returns 0 (obviously a move is not caused by a button). Second of all this is an event handler for MainWindow and not the combobox.


I have a method open_file and in the first case I choose proper file from C: disk (QfileDialog) in second case the same file is downloaded from server and write for example on C: disk.
In second case I know file path so I do not know to choose file once again but used path which was chosen before writing file.

How to skip the part of code which open Qfiledialog.

Why don't you store the path in some variable and if the variable is not empty you will know you already have the path?

arturs
28th May 2015, 21:27
I made a mistake. I do not know Why I used Mosemove...




void QComboBox::mousePressEvent(QMouseEvent *event)
{
if (event->button()==Qt::LeftButton) emit clicked();

}

but know I have the error: 'clicked' was not declared in this scope

something is wrog I am a bit confused

wysota
29th May 2015, 00:34
You cannot define a handler for a class which already exists. You need to subclass QComboBox and use an instance of your subclass instead of QComboBox. Alternatively you can apply an event filter on the existing combobox if you want to avoid subclassing however this will make your code messy.

arturs
29th May 2015, 17:04
I created the following code:



#include "mycombobox.h"

MyCombobox::MyCombobox(QWidget *parent) : QComboBox(parent)
{

}

MyCombobox::~MyCombobox()
{

}

void MyCombobox::mousePressEvent(QMouseEvent *event)
{

if (event->button()==Qt::LeftButton) emit clicked();

}



#ifndef MYCOMBOBOX_H
#define MYCOMBOBOX_H

#include <QObject>
#include <QWidget>
#include <QComboBox>
#include <QMouseEvent>

class MyCombobox : public QComboBox
{
Q_OBJECT

public:
MyCombobox(QWidget *parent =0 );
~MyCombobox();

protected:

void mousePressEvent(QMouseEvent *);

signals:

void clicked(void);

};

#endif // MYCOMBOBOX_H



but something is wrong I have the following errors: undefined reference to `vtable for MyCombobox' and I do not know what is wrong :(

Thank you for your patience :)

wysota
29th May 2015, 17:22
Do you mean the solution ?

I don't understand what you mean. Does it work?

arturs
29th May 2015, 17:43
I edited my previous post because I sent it by my mistake

Radek
29th May 2015, 19:15
I do not know what is wrong, either. IMO, the code should work. Try:
(1) Remove QObject and QWidget includes - they are included by QComboBox
(2) Add "virtual" specifiers to the dtor and the mouse handler. Well, you need not according to the C++ specification - because both methods are already virtual.
(3) Remove the "void" parameter from clicked(). Well, the "old" syntax is still legal but contemporary C++ is rather "clicked()" than "clicked(void)"
(3) If it does not help, delete the compiled files directory and make Creator to build everything from (real) scratch.

arturs
29th May 2015, 19:17
#include "mycombobox.h"

MyCombobox::MyCombobox(QWidget *parent) : QComboBox(parent)
{

}

MyCombobox::~MyCombobox()
{

}



#ifndef MYCOMBOBOX_H
#define MYCOMBOBOX_H

#include <QObject>
#include <QWidget>
#include <QComboBox>

class MyCombobox : public QComboBox
{
Q_OBJECT
public:
MyCombobox(QWidget *parent = 0);
~MyCombobox();
};

#endif // MYCOMBOBOX_H

The error is when I only use the above code without QMouseEvent etc

stampede
29th May 2015, 19:50
Code looks ok. Be sure to include 'mycombobox.h' in the HEADERS list in .pro file and re-run qmake.
Can you verify that "moc_mycombobox.cpp" file is created somewhere under the build directory ?

arturs
29th May 2015, 20:18
It was not moc_mycom....

I deleted all files from catalogue where are files moc* etc and rebuild project once again. Now Everything is ok.

Thank you for help

Added after 20 minutes:

Ok. It works after clicking is emited signal ... but I lost rest of action of QCombobox :( Only cliking works.

wysota
29th May 2015, 20:26
Ok. It works after clicking is emited signal ... but I lost rest of action of QCombobox :( Only cliking works.

Because you are not calling the base-class implementation of the event handler.

arturs
29th May 2015, 20:46
What Should I change in my code ?

stampede
29th May 2015, 21:10
Call the base-class implementation of the event handler :) No Qt magic here, just the standard C++ way to call the base-class implementation of virtual method in derived class.

arturs
31st May 2015, 11:32
My present code:



void MyComboBox::mousePressEvent(QMouseEvent *event)
{



if (event->button()==Qt::LeftButton) emit clicked();

else {

QComboBox::mousePressEvent(event);

}
}



In standard QCombobox implementation leftbutton of mouse expands a list, but now after clicking mouse is emited signal (it is clear) so I cannot expand the list.
something I do not understand but I do not know what. Where to call base -class.

My application is:

I have a qCombobox and there is list of available com ports. If a port is uninstalled or new installed I would like to refresh my com ports list automatically.

Maybe is better way to do it.

Regards
Artur

wysota
31st May 2015, 21:15
In standard QCombobox implementation leftbutton of mouse expands a list, but now after clicking mouse is emited signal (it is clear) so I cannot expand the list.
something I do not understand but I do not know what. Where to call base -class.

You need to develop some logic around your code. Your current code says "if left mouse button is clicked on the combobox, emit a clicked() signal, otherwise (not left mouse button is clicked) do whatever a regular combobox does". Your code doesn't say anything about the combo being empty or anything like that. The compiler does not browse the Internet while compiling your code and it will not encounter this thread and thus it will not know what you meant your code to do. You need to explicitly tell it what you want it to do by writing C++ code that implements the algorithm that solves your problem.


I have a qCombobox and there is list of available com ports. If a port is uninstalled or new installed I would like to refresh my com ports list automatically.

Maybe is better way to do it.
Surely there is :) Rebuild the list whenever you detect a set of available ports is modified.

ChrisW67
31st May 2015, 21:26
Rerun qmake after adding/removing the Q_OBJECT macro, then rebuild.

Err... Ignore me, I missed a whole set of replies.

arturs
31st May 2015, 21:47
You need to develop some logic around your code. Your current code says "if left mouse button is clicked on the combobox, emit a clicked() signal, otherwise (not left mouse button is clicked) do whatever a regular combobox does". Your code doesn't say anything about the combo being empty or anything like that. The compiler does not browse the Internet while compiling your code and it will not encounter this thread and thus it will not know what you meant your code to do. You need to explicitly tell it what you want it to do by writing C++ code that implements the algorithm that solves your problem.

I understand :) not possible to have to action using one button of mouse :) Now I use left button to expands the list of Combobox and right to refresh list of ports.


Surely there is :) Rebuild the list whenever you detect a set of available ports is modified.


Which is the best way. Unfortunately there is no signal which will inform me about it

wysota
31st May 2015, 21:53
I understand :) not possible to have to action using one button of mouse :) Now I use left button to expands the list of Combobox and right to refresh list of ports.
That's not what I meant.


Which is the best way. Unfortunately there is no signal which will inform me about it
I have no idea how you fetch the list of ports so I cannot suggest a way to refresh that list.

arturs
31st May 2015, 22:14
That's not what I meant..

It works :) After emiting signal receiver refresh list of ports and showlist :) so I can have many action for one button :)

Thank you for your help and for your patience.

Last question :)

Everytime when I receive a data from Qserialport my aplication is closed (after receiving) for a long time and always with error.
If I do not receive any data then the aplication is closed very fast with code 0