QListView not displaying in Mac OS - c++

I am trying to display a very simple and short list of countries using QStringListModel and QListView. But when I compile it, I get a blank window.
This is the code for my class :
#include "FenPrincipale.h"
FenPrincipale::FenPrincipale()
{
QVBoxLayout *layout = new QVBoxLayout;
QStringList listePays;
listePays << "France" << "Espagne" << "Italie" << "Portugal" << "Suisse";
QStringListModel *modele = new QStringListModel(listePays);
QListView *vue = new QListView;
vue->setModel(modele);
layout->addWidget(vue);
setLayout(layout);
}
The header :
#ifndef FENPRINCIPALE_H
#define FENPRINCIPALE_H
#include <QMainWindow>
#include <QVBoxLayout>
#include <QStringList>
#include <QListView>
#include <QStringListModel>
class FenPrincipale : public QMainWindow
{
Q_OBJECT
public:
FenPrincipale();
};
#endif // FENPRINCIPALE_H
The main :
#include "FenPrincipale.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FenPrincipale w;
w.show();
return a.exec();
}
The pro file :
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = utilisationModeleSimple
TEMPLATE = app
SOURCES += main.cpp\
FenPrincipale.cpp
HEADERS += FenPrincipale.h
FORMS += FenPrincipale.ui
I am currently using Qt Creator 3.3.0 based on Qt 5.4.0 (Clang 6.0 (Apple), 64 bit); OS X Yosemite 10.10.2
What is the problem with this code?

If you want to use QMainWindow, then you need to set your widget as central: QMainWindow::​setCentralWidget. There are good samples in Qt documentation.
FenPrincipale::FenPrincipale()
{
QStringList listePays;
listePays << "France" << "Espagne" << "Italie" << "Portugal" << "Suisse";
QStringListModel *modele = new QStringListModel(listePays);
QListView *vue = new QListView;
vue->setModel(modele);
setCentralWidget( vue );
}
If you don't need QMainWindow functionality, then simply interhit QWidget instead of QMainWindow - and your code will work.

Related

QT/C++ Call function of a widget using a slot

Consider following main.cpp (the only file of the whole Qt-project):
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>
#include <QObject>
#pragma once
class collectedFunctions : public QObject
{
Q_OBJECT
public:
collectedFunctions(QObject* parent = 0) {};
~collectedFunctions() {};
public slots:
void setFunc() {
//Calculate 2+2 and change text of the label accordingly
}
};
#include "main.moc"
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
QWidget window;
window.resize(200, 200);
window.setWindowTitle("Test-GUI");
QVBoxLayout layout(&window);
QPushButton button(&window);
button.setText("Test");
button.show();
QLabel *label = new QLabel(&window);
label->setText("Hello");
collectedFunctions testingFuncs;
QObject::connect(&button, &QPushButton::clicked, &testingFuncs, &collectedFunctions::setFunc);
layout.addWidget(&button);
layout.addWidget(label);
window.show();
return app.exec();
}
My goal with this code is to create a slot that runs a function which the programmer defines (similar to the pyqt-implementation of the signals and slots system). The code above successfully compiles, not throwing any errors and so far meeting my expectations. Yet as soon I want to manipulate a widget (which in this case is the label), the setfunc-slot does not find the defined label. How can I manipulate a widget using this slot (e.g. using setText() at a label or addItems() at a combobox) or generally have them being recognized in the slot.
Update:
Thanks to the solution of this question, I figured that I could simply use a lambda instead of the Q_OBJECT makro, so I removed the header-code and then changed the connect from the Button to following:
QObject::connect(&button, &QPushButton::clicked, [&label](){
int num = 2 + 2;
string text = "2+2 = ";
text += std::to_string(num);
QString qtext = QString::fromStdString(text);
label->setText(qtext); });
you shouldn't use the Q_OBJECT macro in main.cpp.
The Q_OBJECT macro must appear in the private section of a class
definition that declares its own signals and slots or that uses other
services provided by Qt's meta-object system.
The moc tool reads a C++ header file. If it finds one or more class
declarations that contain the Q_OBJECT macro, it produces a C++ source
file containing the meta-object code for those classes. Among other
things, meta-object code is required for the signals and slots
mechanism, the run-time type information, and the dynamic property
system.
The C++ source file generated by moc must be compiled and linked with
the implementation of the class.
When you have your class defined in .cpp file instead of .h file moc fails to process it properly.
you need a separate file for class:
in collectedfunctions.h
#pragma once
#include <QObject>
class collectedFunctions: public QObject
{
Q_OBJECT
public:
collectedFunctions(QObject *parent = 0);
~collectedFunctions();
public slots:
void setFunc();
};
and in collectedfunctions.cpp
#include "collectedfunctions.h"
#include <QDebug>
collectedFunctions::collectedFunctions(QObject *parent)
{
}
collectedFunctions::~collectedFunctions()
{
}
void collectedFunctions::setFunc()
{
qDebug() << "2+2 = " << 2 + 2;
}
and in your main.cpp
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>
#include "collectedfunctions.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget window;
window.resize(200, 200);
window.setWindowTitle("Test-GUI");
QVBoxLayout layout(&window);
QPushButton button(&window);
button.setText("Test");
button.show();
QLabel *label = new QLabel(&window);
label->setText("Hello");
collectedFunctions testingFuncs;
QObject::connect(&button, &QPushButton::clicked, &testingFuncs, &collectedFunctions::setFunc);
layout.addWidget(&button);
layout.addWidget(label);
window.show();
return app.exec();
}
don't forget to add QT +=core gui widgets in your .pro file.
Result:
If you want to change QLabel Text :
in collectedfunctions.h
#pragma once
#include <QObject>
class collectedFunctions: public QObject
{
Q_OBJECT
public:
explicit collectedFunctions(QObject *parent = 0);
~collectedFunctions();
signals:
void updateLable(int num);
public slots:
void setFunc();
private:
int num = 0;
};
and in collectedfunctions.cpp
#include "collectedfunctions.h"
#include <QDebug>
collectedFunctions::collectedFunctions(QObject *parent)
{
}
collectedFunctions::~collectedFunctions()
{
}
void collectedFunctions::setFunc()
{
qDebug() << "2+2 = " << 2 + 2;
num++;
emit updateLable(num);
}
and in your main.cpp
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>
#include "collectedfunctions.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget window;
window.resize(200, 200);
window.setWindowTitle("Test-GUI");
QVBoxLayout layout(&window);
QPushButton button(&window);
button.setText("Test");
button.show();
QLabel *label = new QLabel(&window);
label->setText("Hello");
collectedFunctions testingFuncs;
QObject::connect(&button, &QPushButton::clicked, &testingFuncs, &collectedFunctions::setFunc);
QObject::connect(&testingFuncs, &collectedFunctions::updateLable, [&label](int num)
{
qDebug() << "Number = " << num;
label->setText(QString::number(num));
});
layout.addWidget(&button);
layout.addWidget(label);
window.show();
return app.exec();
}
you can see:

Show tooltip at mouse position and show legend on top-right corner

The following toy problem show two tabs, each tab contains a QGridLayout, which has a ScrollArea on one of the cells, which in turn contains a customized QLabel (MyLabel). When the user moves his mouse on the customzied QLabel, a tooltip shows up for several seconds.
test.pro
QT += core gui widgets
CONFIG += c++17
CONFIG += debug
QMAKE_CXXFLAGS += -std=c++17
SOURCES += \
test.cpp
QMAKE_CLEAN += $$TARGET Makefile
HEADERS += \
mywidget.h
test.cpp
#include "mywidget.h"
#include <QApplication>
#include <QtGui>
#include <QtCore>
#include <QtWidgets>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyMainWindow myMainWindow;
myMainWindow.show();
return a.exec();
}
mywidget.h
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QDebug>
#include <QWidget>
#include <QMdiArea>
#include <QMainWindow>
#include <QScrollArea>
#include <QLabel>
#include <QGridLayout>
#include <QMouseEvent>
#include <QToolTip>
class MyLabel : public QLabel
{
Q_OBJECT
public:
MyLabel(QWidget *parent=nullptr, const QString &name="")
: QLabel(parent), m_name(name)
{
resize(1800, 1200);
setMouseTracking(true);
}
private:
void mouseMoveEvent(QMouseEvent *ev) override {
QToolTip::showText(
ev->globalPosition().toPoint()
, m_name + ": " + QString::number(ev->pos().x()) + ", " + QString::number(ev->pos().y())
);
QLabel::mouseMoveEvent(ev);
}
private:
QString m_name;
};
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget* parent = nullptr, const QString &name="")
: QWidget(parent), m_name(name)
{
setWindowTitle(name);
m_gridLayout = new QGridLayout(this);
this->setLayout(m_gridLayout);
// layout col 1
m_gridLayout->addWidget(new QLabel("smaller label", this), 0, 0);
// layout col 2
m_scrollArea = new QScrollArea(this);
MyLabel *label = new MyLabel(this, m_name);
m_scrollArea->setWidget(label);
m_gridLayout->addWidget(m_scrollArea, 0, 1);
}
private:
QString m_name;
QGridLayout *m_gridLayout;
QScrollArea *m_scrollArea;
};
class MyMainWindow : public QMainWindow
{
Q_OBJECT
public:
MyMainWindow(QWidget* parent = nullptr)
: QMainWindow(parent)
{
m_mdiArea = new QMdiArea(this);
this->setCentralWidget(m_mdiArea);
MyWidget *myWidget1 = new MyWidget(this, "widget 1");
m_mdiArea->addSubWindow(myWidget1);
MyWidget *myWidget2 = new MyWidget(this, "widget 2");
m_mdiArea->addSubWindow(myWidget2);
m_mdiArea->setViewMode(QMdiArea::ViewMode::TabbedView);
}
private:
QMdiArea *m_mdiArea;
};
#endif // MYWIDGET_H
Here are two problems that I am struggling with:
How can I show the tooltip without moving my mouse when I toggle between those two tabs by Ctrl+Tab? In my real-world problem, I use the tooltip show information about data at the mouse point.
Is it possible show some legends on the top-right corner of the viewport of the QScollArea, regardless of the positions of the scoll bars? I am trying with paintEvent, but had difficulties get the position adjusting according to scoll bars.
Cursor postion can be retrieved by using QCursor::pos(), so both problems can be sovlved by using QCuros::pos() in paintEvent. I was confused by the fact paintEvent does not directly provide cursor position, as mouseMoveEvent does.

Regarding Projector Programming using QT

I am connecting the projector to Quectel QCOM application. Now I want to skip that application and create my customized application to control the projector.
I wrote a program based on the guidelines of Quectel to switch off the projector. Following is the code. Even I used the QSerialPort code. But the projector couldn't switch off. However using the command prompt of the Quectel QCOM application, I could control the projector.
Please help me in this guys! I am stuck in this since a month.
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec(); //
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include<QSerialPort>
#include<string>
#include<QtGui>
#include <QMessageBox>
using namespace std;
QSerialPort *serial;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow() //
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QMessageBox::information(this,"Title here","Hello World");
serial = new QSerialPort(this);
serial->setPortName("COM3");
serial->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);
serial->setDataBits(QSerialPort::Data8);
serial->setFlowControl(QSerialPort::NoFlowControl);
serial->setStopBits(QSerialPort::OneStop);
serial->setParity(QSerialPort::NoParity);
if(!serial->open(QIODevice::ReadWrite))
{
qDebug()<<"error: can't open com port";
}
QString command = "WT+LEDE=0\n";
QByteArray x = command.toLocal8Bit();
serial->write(x);
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
QMake project file:
#-------------------------------------------------
Project created by QtCreator 2019-11-02T10:55:21
#-------------------------------------------------
QT += core gui serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = GUISerialPort
TEMPLATE = app
SOURCES += main.cpp
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui

Qt::FramelessWindowHint setSizeConstraint sideffects on closeevent

When using Qt::FramelessWindowHint with setSizeConstraint my widget does not recieve close events anymore, is this a bug? Minimal test example:
pro
QT += core gui
TARGET = QT-BUG
TEMPLATE = app
SOURCES += main.cpp\
widget.cpp
HEADERS += widget.h
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget(){}
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QCloseEvent>
Widget::Widget(QWidget *parent) : QWidget(parent)
{
setWindowFlags(Qt::Tool
| Qt::FramelessWindowHint
| Qt::WindowStaysOnTopHint);
QVBoxLayout *l2 = new QVBoxLayout(this);
l2->setSizeConstraint(QLayout::SetFixedSize);
this->setLayout(l2);
QLineEdit* _inputLine = new QLineEdit(this);
l2->addWidget(_inputLine);
}
main .cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
Window events like Close and Minimize are actually tied to the existence of buttons. Bit of a poor design choice by the Qt folks.
It seems that Qt::FramelessWindowHint removes/disables the buttons, but you can re-enable them (without displaying them) via other window hints. For close events, add Qt::WindowCloseButtonHint.

how to use QWinThumbnailToolBar with QMainWindow

I want to try QWinThumbnailToolBar in Qt 5.2 but it doesn't work !(Program runs but there is no thumbnail !!!!)
//main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWinThumbnailToolButton>
#include <QWinThumbnailToolBar>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QWinThumbnailToolBar* thumbnailToolBar;
QWinThumbnailToolButton *playToolButton;
QWinThumbnailToolButton *forwardToolButton;
QWinThumbnailToolButton *backwardToolButton;
};
#endif // MAINWINDOW_H
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
thumbnailToolBar = new QWinThumbnailToolBar(this);
thumbnailToolBar->setWindow(this->windowHandle());
playToolButton = new QWinThumbnailToolButton(thumbnailToolBar);
playToolButton->setEnabled(false);
playToolButton->setToolTip(tr("true"));
playToolButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
forwardToolButton = new QWinThumbnailToolButton(thumbnailToolBar);
forwardToolButton->setEnabled(true);
forwardToolButton->setToolTip(tr("Fast forward"));
forwardToolButton->setIcon(style()->standardIcon(QStyle::SP_TrashIcon));
backwardToolButton = new QWinThumbnailToolButton(thumbnailToolBar);
backwardToolButton->setEnabled(true);
backwardToolButton->setToolTip(tr("Rewind"));
backwardToolButton->setIcon(style()->standardIcon(QStyle::SP_MediaSeekBackward));
thumbnailToolBar->addButton(backwardToolButton);
thumbnailToolBar->addButton(playToolButton);
thumbnailToolBar->addButton(forwardToolButton);
}
MainWindow::~MainWindow()
{
delete ui;
}
//pro file :
QT += core gui winextras multimedia
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = untitled1
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
I think the problem is with these two line :
thumbnailToolBar = new QWinThumbnailToolBar(this);
thumbnailToolBar->setWindow(this->windowHandle());
I also tried to use QWidget instead of QMainWindow...
How can I fix it ??
Your code to create QWinThumbnailToolBar is correct, the problem is where you create it. I think creating it in the window constructor is the problem (Maybe because the window handle is not ready yet). You can make something like this:
// main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FrmMain w;
w.show();
w.createThmbBar();
return a.exec();
}
Where createThumbBar() is a public function where you create the QWinThumbnailToolBar as in:
// MainWindow.cpp
void MainWindow::createThmbBar()
{
thumbnailToolBar = new QWinThumbnailToolBar(this);
thumbnailToolBar->setWindow(this->windowHandle());
playToolButton = new QWinThumbnailToolButton(thumbnailToolBar);
playToolButton->setEnabled(false);
playToolButton->setToolTip(tr("true"));
playToolButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
forwardToolButton = new QWinThumbnailToolButton(thumbnailToolBar);
forwardToolButton->setEnabled(true);
forwardToolButton->setToolTip(tr("Fast forward"));
forwardToolButton->setIcon(style()->standardIcon(QStyle::SP_TrashIcon));
backwardToolButton = new QWinThumbnailToolButton(thumbnailToolBar);
backwardToolButton->setEnabled(true);
backwardToolButton->setToolTip(tr("Rewind"));
backwardToolButton->setIcon(style()->standardIcon(QStyle::SP_MediaSeekBackward));
thumbnailToolBar->addButton(backwardToolButton);
thumbnailToolBar->addButton(playToolButton);
thumbnailToolBar->addButton(forwardToolButton);
}
Late answer but hopefully it could help anyone faces the same issue later.
The fix that #Ramez proposed works however I am getting a crash on application shutdown due to the windows extra. Is there something special I need to do myself in the destructor? The QWindow has already been deleted when the QWinThumbnailToolBarPrivate::hasHandle() checks for the handle.
Exception thrown: read access violation.
d was 0xFFFFFFFFFFFFFF7F.
QPlatformWindow *QWindow::handle() const
{
Q_D(const QWindow);
return d->platformWindow;
}
Stack Trace Below:
Qt5Guid.dll!QWindow::handle() Line 1929 C++
Qt5WinExtrasd.dll!QWinThumbnailToolBarPrivate::hasHandle() Line 460 C++
Qt5WinExtrasd.dll!QWinThumbnailToolBarPrivate::handle() Line 465 C++
Qt5WinExtrasd.dll!QWinThumbnailToolBarPrivate::nativeEventFilter(const QByteArray & __formal, void * message, long * result) Line 549 C++
Qt5Cored.dll!QAbstractEventDispatcher::filterNativeEvent(const QByteArray & eventType, void * message, long * result) Line 484 C++
[External Code]
Qt5Guid.dll!QWindowPrivate::destroy() Line 1914 C++
Qt5Guid.dll!QWindow::destroy() Line 1864 C++
Qt5Widgetsd.dll!QWidgetPrivate::deleteTLSysExtra() Line 1891 C++
Qt5Widgetsd.dll!QWidget::destroy(bool destroyWindow, bool destroySubWindows) Line 12515 C++
Qt5Widgetsd.dll!QApplication::~QApplication() Line 798 C++