orbit orbit - 1 month ago 7
C++ Question

Implementing a shift-click modifier to a specific form widget?

If I use Qt Designer for my application's main window -- and the application contains many different widgets inside of it -- how do I further customize those widgets sepcifically? For example, I have a

QTableView
widget inside of my main application. Upon debugging the application, a
ui_myapplication.h
file gets created from the Qt Designer
.ui
form. Suppose I wanted to add some extra things to the widgets defined in that file. How would I if it's created at runtime?

Example:

In
myApplication.cpp
, I have this block of code:

void myApplication::mousePressEvent(QMouseEvent* event) {
if(event->modifiers() & Qt::ShiftModifier) {
if(event->button() == Qt::LeftButton) {
qDebug() << "shift modifier";
ui->tableView->setSortingEnabled(false);
}
}
}


This is similar to what I want, but not exactly. The idea is to have the
QTableView
widget named
tableView
(which is contained within the main application that I created in Qt Designer) to disable the table's sorting functionality when I hold
Shift
and left-click a column header. (the end goal is to make it so that Shift+clicking will disable column sorting for a short while so I can select all items in the column instead of having it sort the column).

The code above will only work if I Shift+Click the very bottom of the main application (in the space where there are no other widgets). That makes sense. But how do I make it so that doing a Shift+click inside the
tableView
widget will trigger the
qDebug() << "shift modifier";
line?

I'd want something similar to this: (pseudocode):

void myApplication::mousePressEvent(QMouseEvent* event) {
if(target == ui->tableView->horizontalheader() && event->modifiers() & Qt::ShiftModifier) {
if(event->button() == Qt::LeftButton) {
qDebug() << "shift modifier";
ui->tableView->setSortingEnabled(false);
}
}
}


How can I do this?

EDIT: research had led me to believe I can do this with an event filter that could target a specific widget. Am I on the right track?

EDIT 2: Thanks to goug's answer below, I was able to accomplish what I needed by subclassing
QTableView
and then promoting my existing form's
QTableView
to the new class. See below:

mytableview.h

#ifndef MYTABLEVIEW_H
#define MYTABLEVIEW_H

#include "mytableview.h"
#include <QTableView>

class MyTableView : public QTableView
{
Q_OBJECT

public:
explicit MyTableView(QWidget * parent = 0);

~MyTableView();

protected:
void mousePressEvent(QMouseEvent *event);

};

#endif // MYTABLEVIEW_H


mytableview.cpp

#include "mytableview.h"
#include <QDebug>

MyTableView::MyTableView(QWidget* parent)
{
}

MyTableView::~MyTableView()
{
}

void MyTableView::mousePressEvent(QMouseEvent* event) {
if(event->modifiers() & Qt::ShiftModifier) {
if(event->button() == Qt::LeftButton) {
qDebug() << "shift modifier";
setSortingEnabled(false);
}
}
}

Answer

There's a couple of different approaches you could use here. You could subclass QTableView, and then in Qt Designer, you place a QTableView as normal, but then promote it to your derived class. The generated code creates an instance of your class rather than QTableView. In Qt Designer, right-click on the table view and select from the Promote options. You'll have to enter your class details the first time. I'd be inclined to go this route especially if there's other custom behavior you want to implement on the table view.

Another option is to create a new class and install it as an event filter on your QTableView. Your new class then gets the events before they go to the QTableView and you can act accordingly on them. Look up installEventFilter in Qt Assistant, and that'll get you to the details of how to do this.

Comments