I was wondering if there was a way I could remove all keyboard shortcuts from the UI so I can use the event filter to grab key commands instead.
Currently, I have this in my eventFilter() function and it does the job but it also affects the QSliders, QLineEdits and QButtons I have on there - and I don't want it to.
bool LinkControl::eventFilter(QObject *o, QEvent *e)
{
QKeyEvent *keyEvent = NULL;
// qDebug() << "TYPE: " << e->type();
switch(e->type())
{
case 51:
// qDebug() << this->overrideControl;
if(this->overrideControl == true)
{
keyEvent = static_cast<QKeyEvent*>(e);
// this->handleKeyboardInput(true, keyEvent->key());
// emit handleInput(true, keyEvent->key());
this->handleKeyboardInput(true, keyEvent->key());
// qDebug() << "PRESS: " << keyEvent->key();
}
this->overrideControl = !this->overrideControl;
return true;
break;
case QEvent::KeyRelease:
keyEvent = static_cast<QKeyEvent*>(e);
// this->handleKeyboardInput(false, keyEvent->key());
// emit handleInput(false, keyEvent->key());
this->handleKeyboardInput(false, keyEvent->key());
// qDebug() << "RELEASE: " << keyEvent->key();
return true;
break;
default:
return QMainWindow::eventFilter(o, e);
}
}
For example, In my handleKeyboardInput function, I have the up arrow key increment a value and it does that but it also moves a QSlider if it's selected.
Thank you.
Related
I have a qt and cpp application that creates threads on create button and runs them with a certain start time specified by the user. It list the thread object created into a QListWidget in the application with some random id generated. I can select and delete the QListWidget item as shown below.
void MainWindow::on_stopPushButton_clicked()
{
qDebug() << mythread->threadIdGenerator();
QList<QListWidgetItem*> items = ui->threadWithId->selectedItems();
foreach(QListWidgetItem* item, items){
ui->threadWithId->removeItemWidget(item);
delete item; // Qt documentation warnings you to destroy item to effectively remove it from QListWidget.
}
}
This delete operation just deletes the entry from the UI (QListWidget) of the application but the thread deleted from QListWidget is still running in the application.
My question is how can I get terminate this thread with deletion from the QListWidget from the UI of the application?
Or is there any way to get this thread object and delete it after being selected from the UI.
Update
void MainWindow::on_createNewThreadButton_clicked()
{
qDebug(" in create new thread slot");
mythread = new MyThread(this);
mythread->threadOccuranceTime = ui->insertThreadTimeoutHere->text().toInt();
mythread->start();
myThreadListCreatedObjects.append(mythread);
connect(mythread, SIGNAL(signalForThreadMessage(int)), this, SLOT(displayThreadMessages(int)));
connect(mythread, SIGNAL(sendThreadId(int)), this, SLOT(displayThread(int)));
}
MyThread.cpp
int MyThread::threadIdGenerator()
{
qDebug(" in threadIdGenerator function");
// qDebug() << 1 + (rand() % 100);
srand(time(0));
return 1 + (rand() % 100);
}
void MyThread::run()
{
this->threadId = 0;
qDebug() << this->threadId;
qDebug(" in run function for the thread");
this->threadId = this->threadIdGenerator();
qDebug(" id inside the run method of thread");
qDebug() << threadId;
emit sendThreadId(threadId);
while (1) {
msleep(this->threadOccuranceTime);
emit signalForThreadMessage(this->threadId);
}
}
I used QList to store all the threads created, and when a item is selected in the QLIstWidget I tried to get the thread with that id property, terminate it and then remove from the QListWidget from UI as shown below.
void MainWindow::on_stopPushButton_clicked()
{
QList<QListWidgetItem*> items = ui->threadWithId->selectedItems();
foreach(QListWidgetItem* item, items){
qDebug() << "the item selected to delete";
qDebug() << item->text();
ui->threadWithId->removeItemWidget(item);
QString selected = item->text();
QString subString = selected.mid(0,2);
qDebug() << "subString = ";
qDebug() << subString;
for(MyThread *sp:myThreadListCreatedObjects){
qDebug() << "thread id = ";
qDebug() << sp->threadId;
if(sp->threadId == subString.toInt()){
qDebug() << "subString = ";
qDebug() << subString;
sp->terminate();
delete sp;
}
}
delete item; // Qt documentation warnings you to destroy item to effectively remove it from QListWidget.
}
}
I am not sure this is the correct way of doing the things but it works some how. Any better solution is welcome :).
I expect my program to print "mouse on label name" when my mouse is located on the labelname (a QLabel), and to print"mouse not on label name" when my mouse is not located on the labelname.
Even though I put my mouse on labelname, my program prints "mouse not on label name".
How can I know when my mouse is not on the labelname?
bool Dialog::eventFilter(QObject *obj, QEvent *e)
{
if(qobject_cast<QLabel*>(obj) == ui->labelname) {
cout << “mouse on label name” << endl;
}else if(qobject_cast<QLabel*>(obj) != ui->labelname) {
cout << “mouse not on label name” << endl;
}
return false;
}
Be sure you are installing the event filter correctly. Also, if you want to track mouse position you have to enable mouseTracking, otherwise the move events won't be triggered (though QEvent::Enter and QEvent::Leave will, which are the ones that indicates the mouse has entered or left the widget).
Here a minimal example of how to do it:
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
m_label = new QLabel("Hello world!");
m_label->setObjectName("m_label");
m_label->installEventFilter(this);
m_label->setMouseTracking(true);
auto hlayout = new QVBoxLayout();
hlayout->addWidget(m_label);
setLayout(hlayout);
}
bool MyWidget::eventFilter(QObject* sender, QEvent* event)
{
if (sender == m_label) {
qDebug() << sender->objectName() << event->type();
if (event->type() == QEvent::Enter) {
qDebug() << "mouse on label name";
} else if (event->type() == QEvent::Leave) {
qDebug() << "mouse not on label name";
}
}
return QWidget::eventFilter(sender, event);
}
The full working example is available in GitHub.
I've got a custom model derived from QAbstractItemModel.
data, columnCount,rowCount,parent,index,setData,flags,headerData and setHeaderData have all been overrided.
flags only returns Qt::ItemIsEditable (for future)
But the problem starts with headerData(), it seems messages with Qt::Vertical as orientation never reaches it. So, to my understanding, there can't be any vertical headers.
The code serves well for horizontal though:
QVariant MiModeloCalendarioGeneral::headerData(int section, Qt::Orientation orientation, int role) const
{
qDebug() << "{";
qDebug() << "Role: " << role;
qDebug() << "Section: " << section;
qDebug() << "Orientation: " << orientation;
qDebug() << "}";
if (role != Qt::DisplayRole) {
return QVariant();
}
if (orientation == Qt::Horizontal) {
qDebug() << "Horizontal";
return fileras[section];
}
if (orientation == Qt::Vertical) {
qDebug() << "Vertical";
return cabeceras[section];
}
}
What am I missing?
I've checked that both 'cabeceras' and 'fileras' have content. And the setHeaderData function does emit the headerDataChanged signal.
EDIT: Typo
I am writing a keyboard tester, so I start a dialog with
keybDialog keyboardTestWindow;
keyboardTestWindow.setWindowTitle("Keyboard test");
keyboardTestWindow.exec();
override the keyPressEvent(QKeyEvent *event) and the test works superb. Now, I needed use of some parameters from parent, so instead I did
keybDialog keyboardTestWindow(m_parent);
keyboardTestWindow.setWindowTitle("Keyboard test");
keyboardTestWindow.exec();
and implemented what I needed. Now I discovered that just by instantiating the class and passing the parent to it, my dialog no longer receives the keyPressEvent. Are these passed to m_parent in some way? How can I avoid this?
EDIT:
The beginning of my keyPressEvent:
void keybDialog::keyPressEvent(QKeyEvent *event)
{
ui->txtBxKeyboardInput->clear();
qDebug() << "Event: " << hex << event->key() << event->nativeVirtualKey() << event->modifiers() << event->nativeModifiers() << event->nativeScanCode();
ui->txtBxKeyboardInput->setText(ui->txtBxKeyboardInput->text()+event->text());
switch(sequenceNumber)
{
case 0: // Left Shift + R
if( (event->key() == Qt::Key_R) && event->modifiers() == Qt::ShiftModifier && event->nativeModifiers() == 0x201)
{
reportSuccessfullKey(sequenceNumber);
}
else
{
ui->lblStatus->setText("WRONG");
}
break;
I have a serious problem with QWebView::createWindow() and how to handle creating
new browser window.
I have sub-classed QWebView as told by docs (MyWebView) and reimplemented it's createWindow() method and also it's contextMenuEvent(QContextMenuEvent * event) method so that I could add and change my own menu entries.
The context menu entries "Open Link", "Open Link in New Tab" and "Open Image" all work perfectly and either open the required link/image into same tab if "Open Link" is selected or into a new tab if one of the other three remaining "Open ..." entries is selected. Also, when clicking web pages that want to open in new window they will open in new tab, as expected.
However, I added new menu entry called "Open Link in New Window" and for the life of me can't get it working. It opens completely new browser window but it does not load the clicked url. Even worse, if I manually enter some www address to this new browser window and then try to open new tabs they will open in the old window!!!
Could someone please kindly check what is wrong with my code ?
First, the MyWebView constructor:
MyWebView::MyWebView(QWidget * parent):
QWebView(parent),newWindow(false)
{
this->myPage = new MyWebPage;
this->setPage(this->myPage);
/* Just change text and nothing more ... */
this->action_openLinkInNewWindow = this->pageAction(QWebPage::OpenLinkInNewWindow);
if(this->action_openLinkInNewWindow) {
if(this->action_openLinkInNewWindow->isEnabled()) {
this->action_openLinkInNewWindow->setText("Open Link in New Window");
}
}
}
Then the "Open Image", "Open Link in New Tab" and "Open Link in New Window" functionality
(default "Open Link" worked just fine so I did not need to reimplement that one)
void MyWebView::openImage()
{
#ifndef NDEBUG
qDebug() << "=================================================";
qDebug() << __FUNCTION__ << " called ...";
#endif
this->imageUrl = true;
this->newWindow = false;
this->createWindow(QWebPage::WebBrowserWindow);
}
void MyWebView::openLinkInNewTab()
{
#ifndef NDEBUG
qDebug() << "=================================================";
qDebug() << __FUNCTION__ << " called ...";
#endif
this->linkUrl = true;
this->newWindow = false;
this->createWindow(QWebPage::WebBrowserWindow);
}
void MyWebView::openLinkInNewWindow()
{
#ifndef NDEBUG
qDebug() << "=================================================";
qDebug() << __FUNCTION__ << " called ...";
#endif
this->linkUrl = true;
this->newWindow = true;
this->createWindow(QWebPage::WebBrowserWindow);
}
Then, my reimplemented contextMenuEvent()
void MyWebView::contextMenuEvent(QContextMenuEvent * event)
{
#ifndef NDEBUG
qDebug() << "=================================================";
qDebug() << __FUNCTION__ << " called ...";
#endif
this->rel_pos = event->pos();
QWebHitTestResult r = page()->mainFrame()->hitTestContent(event->pos());
QMenu menu(this);
if (!r.linkUrl().isEmpty()) {
menu.addAction(pageAction(QWebPage::OpenLink));
menu.addAction(tr("Open Link in New Tab"), this, SLOT(openLinkInNewTab()));
menu.addAction(tr("Open Link in New Window"),this,SLOT(openLinkInNewWindow()));
menu.addAction(pageAction(QWebPage::DownloadLinkToDisk));
menu.addAction(pageAction(QWebPage::CopyLinkToClipboard));
menu.addSeparator();
}
if(!r.imageUrl().isEmpty()) {
menu.addAction(tr("Open Image"),this,SLOT(openImage()));
menu.addAction(pageAction(QWebPage::DownloadImageToDisk));
menu.addAction(pageAction(QWebPage::CopyImageToClipboard));
menu.addAction(pageAction(QWebPage::CopyImageUrlToClipboard));
}
if(!r.linkUrl().isEmpty() || !r.imageUrl().isEmpty()) {
menu.exec(mapToGlobal(rel_pos));
return;
}
QWebView::contextMenuEvent(event);
}
And finally, the problematic createWindow()
QWebView* MyWebView::createWindow(QWebPage::WebWindowType type)
{
#ifndef NDEBUG
qDebug() << "=================================================";
qDebug() << __FUNCTION__ << " called ...";
#endif
switch(type) {
case QWebPage::WebBrowserWindow:
{
QWebHitTestResult hitTest = this->page()->mainFrame()->hitTestContent(rel_pos);
QUrl url;
if(this->linkUrl) {
url = hitTest.linkUrl();
this->linkUrl = false;
}
if(this->imageUrl) {
url = hitTest.imageUrl();
this->imageUrl = false;
}
if(newWindow) {
/* This does not work!!!!*/
MainWindow *mw = new MainWindow;
mw ->show();
return mw->currentTab();
} else {
MyBrowser* browser = new MyBrowser(url);
TabbedBrowser::getInstance()->newTab(browser,"Loading ...");
return browser->getwebView();
}
}
break;
}
return QWebView::createWindow(type);
}
If there is anything else with my code, besides createWindow() then I would gladly
hear.
Thank you!