I want to use transient scrollbar (Transient scroll bars appear when the content is scrolled and disappear when they are no longer needed) in Qt application. For this purpose I have inheritanced class QproxyStyle and reimplemented function styleHint. Code placed below.
File ScrollBar.h:
#include <QStyle>
#include <QCommonStyle>
#include <QProxyStyle>
class ScrollBarStyle : public QProxyStyle
{
public:
int styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *hret) const;
};
File ScrollBar.c:
#include "ScrollBar.h"
int ScrollBarStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *widget,QStyleHintReturn *hret) const
{
int ret = 0;
switch (sh) {
case SH_ScrollBar_Transient:
ret = true;
break;
default:
return QProxyStyle::styleHint(sh, opt, widget, hret);
}
return ret;
}
File MainWindow.h:
#include <QMainWindow>
#include <QTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
};
File MainWindow.cpp:
#include <QTextEdit>
#include "MainWindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextEdit *l = new (std::nothrow) QTextEdit(this);
if (l == 0)
return;
setCentralWidget(l);
}
MainWindow::~MainWindow()
{
}
File main.cpp:
#include "ScrollBar.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
ScrollBarStyle *style = new (std::nothrow) ScrollBarStyle;
if(style == 0)
return -1;
style->setBaseStyle(a.style());
w.show();
return a.exec();
}
But I have got a problem: transient scrollbar has been appearing only once (when text doesn't fit in the text area) then it has been disappeared and never come back visible.
So how can I fix this problem?
Thanks!
You have forgotten to set the style to application.
a.setStyle(style);
Related
As on Windows it is useless to write, you can't get the camera screen at all.
What should I do?
Do I need to apply for permission?
Where should I put the file Info.plist?
In your Info.plist you should include:
<key>NSCameraUsageDescription</key>
<string>${PRODUCT_NAME} ...a description of why the camera is used by your app...</string>
Here is an example of displaying the camera input.
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QCamera>
#include <QCameraInfo>
#include <QCameraViewfinder>
#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:
Ui::MainWindow *ui;
QCamera *m_camera;
QList<QCameraInfo> m_cameras;
QCameraViewfinder *m_cameraViewFinder;
private:
bool checkCameraAvailability();
private slots:
void setCamera(const QCameraInfo &cameraInfo);
void on_camerSelectBox_currentTextChanged(const QString &arg1);
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow),
m_cameraViewFinder(new QCameraViewfinder)
{
ui->setupUi(this);
// Detect Cameras
m_cameras = QCameraInfo::availableCameras();
for (const QCameraInfo &cameraInfo : m_cameras) {
ui->camerSelectBox->addItem(cameraInfo.description());
}
// Make sure there is at least one camera available, and start with the default camera as preview.
if(checkCameraAvailability()) {
setCamera(QCameraInfo::defaultCamera());
}
}
MainWindow::~MainWindow()
{
delete m_cameraViewFinder;
delete m_camera;
delete ui;
}
void MainWindow::setCamera(const QCameraInfo &cameraInfo)
{
m_camera = new QCamera(cameraInfo);
m_camera->setViewfinder(m_cameraViewFinder);
ui->previewLayout->addWidget(m_cameraViewFinder);
m_camera->start();
}
bool MainWindow::checkCameraAvailability()
{
if (QCameraInfo::availableCameras().count() > 0)
return true;
else
return false;
}
void MainWindow::on_camerSelectBox_currentTextChanged(const QString &arg1)
{
if(checkCameraAvailability()) {
for (const QCameraInfo &cameraInfo : m_cameras) {
if( cameraInfo.description() == arg1 ) {
setCamera(cameraInfo);
}
}
}
}
In you mainwindow.ui you should include:
A layout named previewLayout
A QComboBox named camerSelectBox
I'm trying to learn c++ so, I try to implement the observer patterns from the book Game Progamming Patterns but I'm always getting Segmentation Fault.
Searching arround I saw that Segmentation fault happens when a program try to access a non allocated memory. So I tried hard to fix it, but I can't. Someone can help me?
Here is my code:
Observer.h
#ifndef OBSERVER_H
#define OBSERVER_H
#include "EntityAndEvent.h"
#include "Subjects.h"
class Observer
{
private:
Observer* next_;
public:
Observer()
: next_(nullptr)
{}
virtual void onNotify(const Entity& entity, Event::Type event) = 0;
// Other stuff...
friend class Subjects;
};
#endif
Achievements.cpp
#ifndef ACHIEVEMENTS_CPP
#define ACHIEVEMENTS_CPP
#include "Observer.h"
#include <vector>
class Achievements : public Observer
{
public:
enum Type{
FELL_OFF,
AWAKE_ON
};
private:
std::vector<Type> done{};
public:
virtual void onNotify(const Entity&, Event::Type);
void unlock(Achievements::Type);
void printDone();
};
void Achievements::onNotify(const Entity& entity, const Event::Type event)
{
switch (event)
{
case Event::Type::ENTITY_FELL:
if(entity.isHero())
unlock(Achievements::Type::FELL_OFF);
break;
case Event::Type::ENTITY_AWAKE:
if(entity.isHero())
unlock(Achievements::Type::AWAKE_ON);
break;
default:
break;
}
};
void Achievements::unlock(Achievements::Type achiev)
{
done.push_back(achiev);
}
void Achievements::printDone()
{
// assert(done.size());
for(size_t i{0}; i < done.size(); i++)
{
std::cout << done[i] << "\n";
}
};
EntityAndEvent.cpp (i create this just to work with observer and subjects)
#ifndef ENTITY_AND_EVENT_H
#define ENTITY_AND_EVENT_H
class Entity
{
public:
inline const bool isHero() const {return true;}
};
class Event
{
public:
enum Type{
ENTITY_FELL,
ENTITY_AWAKE
};
};
#endif
Subjects.h
#ifndef SUBJECT_H
#define SUBJECT_H
#include "Observer.h"
#include <vector>
class Observer;
class Subjects
{
private:
// when implements this, prefer to use linked list or another optimized algorithms
Observer* head_{};
protected:
void notify(const Entity& Entity, Event::Type event);
public:
Subjects() : head_(NULL)
{};
~Subjects() {}
void addObserver(Observer* observer);
// const int getNumObs() const {return num_obs_;}
};
#endif
Subjects.cpp
#include "Subjects.h"
#include <cassert>
void Subjects::notify(const Entity& entity, Event::Type event)
{
Observer* observer = head_;
while (observer != NULL)
{
observer->onNotify(entity, event);
observer = observer->next_;
};
};
void Subjects::addObserver(Observer* observer)
{
if (head_ != nullptr)
observer->next_ = head_;
head_ = observer;
};
Physics.cpp (i create this just to populates the subject)
#ifndef PHYSICS_H
#define PHYSICS_H
#include "Subjects.h"
#include "EntityAndEvent.h"
class Physics: public Subjects
{
private:
public:
void update(const Entity& entity)
{
if (entity.isHero())
{
notify(entity, Event::Type::ENTITY_AWAKE);
};
};
};
#endif
main.cpp
#include "Observer.h"
#include "Achievements.h"
#include "Achievements.cpp"
#include "EntityAndEvent.h"
#include "Physics.h"
#include "Subjects.h"
#include "Subjects.cpp"
int main()
{
Physics *p{};
Entity e{};
Achievements *achiev{};
p->addObserver(achiev);
p->update(e);
return 0;
}
With Physics *p{}; you are declaring a pointer, but it currently does not point to a valid object (it is being initialized as nullptr here). Therefore, calling p->addObserver results in a segmentation fault. You should be able to confirm this by running the program in a debugger.
Why are you using a pointer here? Change Physics *p{}; to Physics p{};.
Disclaimer: Since your code is definitely not a minimum example I didn't look into the whole code or even tried to compile it. I'm only posting an answer because there is a clear error in the main function (use of an invalid pointer) that results in a segmentation fault.
first, tks for the reply. #darcamo that works. I dont know why it was declared as pointer.
I fixed that, so if anyone else have the same doubt check below:
main.cpp
#include "Observer.h"
#include "Achievements.h"
#include "EntityAndEvent.h"
#include "Physics.h"
#include "Subjects.h"
int main()
{
Physics p{};
Entity e{};
Achievements achiev{};
Observer* ptr_achiev{&achiev};
p.addObserver(ptr_achiev);
p.update(e);
return 0;
}
I am new at programming Qt.I have a Gui. It has slider and button. Also I can
get image as input and put it to a second label. The thing that I cannot do
getting pixels of image and change them with respect to the slider value.
#ifndef UI_TEST_H
#define UI_TEST_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
#include <QLabel>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QProgressBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSlider>
#include <QtWidgets/QSplitter>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_TestClass
{
public:
QWidget *centralWidget;
QPushButton *pushButton;
QSplitter *splitter;
QSlider *slider;
QProgressBar *progressBar;
QMenuBar *menuBar;
QMenu *menuTest;
QToolBar *mainToolBar;
QStatusBar *statusBar;
void setupUi(QMainWindow *TestClass)
{
if (TestClass->objectName().isEmpty())
TestClass->setObjectName(QStringLiteral("TestClass"));
TestClass->resize(528, 400);
centralWidget = new QWidget(TestClass);
centralWidget->setObjectName(QStringLiteral("centralWidget"));
pushButton = new QPushButton(centralWidget);
pushButton->setObjectName(QStringLiteral("pushButton"));
pushButton->setGeometry(QRect(50, 230, 75, 23));
splitter = new QSplitter(centralWidget);
splitter->setObjectName(QStringLiteral("splitter"));
splitter->setGeometry(QRect(40, 110, 241, 43));
splitter->setOrientation(Qt::Vertical);
slider = new QSlider(splitter);
slider->setObjectName(QStringLiteral("slide"));
slider->setOrientation(Qt::Horizontal);
splitter->addWidget(slider);
progressBar = new QProgressBar(splitter);
progressBar->setObjectName(QStringLiteral("progressBar"));
progressBar->setValue(24);
splitter->addWidget(progressBar);
TestClass->setCentralWidget(centralWidget);
menuBar = new QMenuBar(TestClass);
menuBar->setObjectName(QStringLiteral("menuBar"));
menuBar->setGeometry(QRect(0, 0, 528, 21));
menuTest = new QMenu(menuBar);
menuTest->setObjectName(QStringLiteral("menuTest"));
TestClass->setMenuBar(menuBar);
mainToolBar = new QToolBar(TestClass);
mainToolBar->setObjectName(QStringLiteral("mainToolBar"));
TestClass->addToolBar(Qt::TopToolBarArea, mainToolBar);
statusBar = new QStatusBar(TestClass);
statusBar->setObjectName(QStringLiteral("statusBar"));
TestClass->setStatusBar(statusBar);
menuBar->addAction(menuTest->menuAction());
retranslateUi(TestClass);
QObject::connect(slider, SIGNAL(valueChanged(int)), progressBar, SLOT(setValue(int)));
QMetaObject::connectSlotsByName(TestClass);
} // setupUi
void retranslateUi(QMainWindow *TestClass)
{
TestClass->setWindowTitle(QApplication::translate("TestClass", "Test", 0));
pushButton->setText(QApplication::translate("TestClass", "Button", 0));
menuTest->setTitle(QApplication::translate("TestClass", "Test", 0));
} // retranslateUi
};
namespace Ui {
class TestClass: public Ui_TestClass {};
} /
#include "test.h"
#include <QtWidgets/QApplication>
#include <QtGui>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Test w;
w.show();
QImage myImage;
myImage.load("Baboon.bmp");
QLabel myLabel;
myLabel.setPixmap(QPixmap::fromImage(myImage));
myLabel.show();
return a.exec();
}
Explanations: I'm trying to create a daemon-script that will be watching the Watch folder and if I drop some files there - it should run the script.
Problem: sometimes after I drop the file - nothing happens
Script: the script is working with files in the Watch folder and deletes them after.
Additional question: do I have to delete mc object manually or it will be done automatically?
main.cpp
#include "widget.h"
#include <QFileSystemWatcher>
#include <QApplication>
#include <QDebug>
#include "myclass.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QFileSystemWatcher watcher;
watcher.addPath("/home/user/Documents/Watch/");
MyClass* mc = new MyClass;
QObject::connect(&watcher, SIGNAL(directoryChanged(QString)), mc, SLOT(showModified(QString)));
return app.exec();
}
myclass.h
#ifndef MYCLASS
#define MYCLASS
#include <QWidget>
#include <QDir>
#include <QDebug>
#include <QProcess>
class MyClass : public QWidget
{
Q_OBJECT
public:
MyClass(QWidget* parent=0)
:QWidget(parent){}
~MyClass(){}
public slots:
void showModified(const QString& str)
{
if(QDir("/home/user/Documents/Watch/").entryInfoList(QDir::NoDotAndDotDot|QDir::AllEntries).count() == 0)
{
qDebug()<<"EEEMPTYYYY!!!!!!!!!!!!!!!!!!!\n";
_status = false;
}
Q_UNUSED(str)
if (_status == false)
{
_status = true;
QProcess *proc = new QProcess();
proc->setWorkingDirectory("/home/user/Documents/");
proc->startDetached("/home/user/Documents/script.sh");
proc->waitForFinished();
delete proc;
}
}
private:
bool _status = false;
};
#endif // MYCLASS
After I upload a file, I am trying to print out its spoolFileName() but although the application runs smoothly it seems as if the string of the name is empty. Any idea where it is wrong? (It's not the size of the file, it's less than 50k)
#include <Wt/WApplication>
#include <Wt/WFileUpload>
#include <Wt/WProgressBar>
#include <Wt/WBreak>
#include <Wt/WContainerWidget>
#include <Wt/WLineEdit>
#include <Wt/WPushButton>
#include <Wt/WText>
#include <Wt/Http/Request>
#include <Wt/WString>
using namespace Wt;
class HelloApplication: public WApplication {
public:
HelloApplication(const WEnvironment& env);
private:
WPushButton *uploadButton;
Wt::WFileUpload *fu;
Wt::WString g;
void greet();
void fileUploaded();
};
HelloApplication::HelloApplication(const WEnvironment& env) :
WApplication(env) {
root()->addStyleClass("container");
setTitle("Hello world"); // application title
fu = new Wt::WFileUpload(root());
fu->setFileTextSize(50); // Set the maximum file size to 50 kB.
fu->setProgressBar(new Wt::WProgressBar());
fu->setMargin(10, Wt::Right);
// Provide a button to start uploading.
uploadButton = new Wt::WPushButton("Send", root());
uploadButton->setMargin(10, Wt::Left | Wt::Right);
// Upload when the button is clicked.
uploadButton->clicked().connect(this, &HelloApplication::greet);
}
void HelloApplication::greet() {
fu->upload();
uploadButton->disable();
fu->uploaded().connect(this, &HelloApplication::fileUploaded);
g = fu->spoolFileName();
}
void HelloApplication::fileUploaded(){ // application title
root()->addWidget(new WText(g.value()));
}
WApplication *createApplication(const WEnvironment& env) {
return new HelloApplication(env);
}
int main(int argc, char **argv) {
return WRun(argc, argv, &createApplication);
}
I think the filename for the spool file is only known after the file is uploaded. Move
g = fu->spoolFileName();
to HelloApplication::fileUploaded().