Custom Qt controls in C++ - c++

I'm trying to use a custom control in Qt, but don't know how.
My current main code:
int main(int argc, char *argv[]) {
QApplication application(argc, argv);
MainWindow window;
window.setWindowState(Qt::WindowMaximized);
window.show();
return application.exec();
}
MainWindow ui has a QTextEdit and a PushButton. Now, I want to use another control that inherits from QTextEdit.
I've added a CodeEditor class that is taken from the documentation, but it doesn't appear in Qt Creator designer.

Related

Qt: How to use slots when object are created in class function

I'm learning Qt quick and want to create a tank game. I create QML components by C++ dynamically. It works great until I use QML signals to connect C++ slots. When the QML emit the signal, C++ fail to receive it and execute the function.
The following code is simplifed.
main.cpp
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
GameMap map;
map.generateMap();
return app.exec();
}
gamemap.cpp
void GameMap::generateMap()
{
Player player;
player.generate(&view);
//QEventLoop loop; //it works when I add these code, but still causes some problems. So I'm wondering if there is other solution?
//loop.exec();
}
player.cpp
void Player::generate(View *view)
{
QQmlComponent component(view.engine(),QUrl("qrc:/Player.qml"));
QObject *myObject=component.create();
QQuickItem *item=qobject_cast <QQuickItem*>(myObject);
QQmlEngine::setObjectOwnership(item, QQmlEngine::CppOwnership);
item->setParentItem(view.rootObject());
item->setParent(&view);
QObject::connect(item,SIGNAL(queryCppFun(QString)),this,SLOT(queryFunction(QString)));
}
void Player::queryFunction(const QString &funName)
{
if(funName=="destroy")
qDebug()<<funName;
}
Player.qml
signal queryCppFun(string funName);
function initDestroy(){
queryCppFun("destroy");
}
OK, I know how to do with it.
Just put static in front of Player player;
And do not handle QML items in C++, thanks #folibis

can't group Push Buttons

i'm trying to group multi (Push Buttons) into an exclusive group, but i don't know how,
when i tried this example [Link] on its own it worked,
but when i try it on my project it failed
NOTE: all my UI elements are graphically implemented not code implemented,
also i'm using (Qt Creator) only
i tried the following
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Test01 window;
QButtonGroup apple (&window);
apple.addButton(&PB01);
apple.addButton(&PB02);
apple.addButton(&PB03);
apple.setExclusive(true);
window.show();
return app.exec();
}
but it didn't work, not the following either
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Test01 window;
QButtonGroup apple (&window);
apple.addButton(&ui->PB01);
apple.addButton(&ui->PB02);
apple.addButton(&ui->PB03);
apple.setExclusive(true);
window.show();
return app.exec();
}
i tried on the cpp file, like the following
Test01::Test01(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Test01)
{
ui->setupUi(this);
QButtonGroup apple (&Test01);
apple.addButton(&ui->PB01);
apple.addButton(&ui->PB02);
apple.addButton(&ui->PB03);
apple.setExclusive(true);
}
but didn't work either
can you please provide the solution
also what's the deference between write this code in (main.cpp) & in (test01.cpp) file
to answer your question correctly, it would be nice to provide the ui-Code of your form.
Howevery, one reason could be, that you missed the checkable property of QPushButton.
To work as a button group every QPushButton must be marked as checkable either by code:
PB01->setCheckable(true);
or by Qt Designer.
Greetings, Thomas

QTGraphicsView allways instantly closes after running outside from main method

I want to create a file that contains and manages the entire UI outside of the main.cpp and its main function.
To start I used the code from this answer, which worked fine
from inside the main method.
To prevent information loss I show the code below as well:
#include ...
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsPixmapItem item(QPixmap("c:\\test.png"));
scene.addItem(&item);
view.show();
return a.exec();
}
I tried to outsource this code into an own
class, but after executing the shown code the just created window
disappeared again within a few milliseconds without a warning or an error.
To check if I made a mistake within my own class I tried to use this code
from an own function within my main.cpp
void initUI(QApplication * application){
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsPixmapItem item(QPixmap(application->applicationDirPath() + "\\graphics\\Theme1\\background.png"));
scene.addItem(&item);
view.show();
}
But the same problem ocurs here. Why does the shown code needs to be executed within the main method, and how could you outsource it?
In case this information helps: I'm running on windows with Qt Creator 3.6.1
based on Qt 5.6.0 (MSVC 2013, 32 bit)
Edit:
Here is my main method
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
initUI(&a);
return a.exec();
}
Edit 2:
The error does not occur when I add an
application->exec();
Can somebody explain why this happens? What is the difference between
the call of application->exec() in the initUI-method and the a.exec() call
within the main method?
The destructors of scene and view are called once you exit initUI, as it is put on the stack. You need to put it on the heap in order to survive after exiting the init function. Of course you should take care of dangling pointers.

Qt C++ connect QPushButton click

I have just started developing using QtGUI and I have checked out some tutorials and documentation, and by what I've read this should work.
#define CONNECT QObject::connect
void test();
QPushButton *lpTestBtn;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtProject w;
w.show();
lpTestBtn = w.window()->findChild<QPushButton*>("TestBtn");
CONNECT(lpTestBtn, SIGNAL(clicked()),qApp,SLOT(test()));
return a.exec();
}
void test()
{
lpTestBtn->setText("Hi");
}
But test() never gets called. Also, lpTestBtn is not null and is found correctly.
I have tried the following changes
CONNECT(lpTestBtn, SIGNAL(clicked()),qApp->activeWindow(),SLOT(test()));
CONNECT(lpTestBtn, SIGNAL(clicked()),w.window(),SLOT(test()));
I know I can just do QtProject::on_TestBtn_clicked(); but I'd like to get it working using CONNECT,SIGNAL and SLOT.
The test function in your code is not a slot, nor does it belong to the Q(Core)Application class as you seem to have used it.
The best would be is to move that one line in the test function to the connection with the lambda syntax. This will require C++11 support, but that is in quite common use these days.
You would use the new shiny signal-slot syntax. This would spare you some headache for runtime issues in the future because they would appear at compilation-time.
Therefore, you would write something like this:
main.cpp
#include <QMainWindow>
#include <QApplication>
#include <QPushButton>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
// Replace it with "QtProject".
QMainWindow w;
w.show();
QPushButton * lpTestBtn = w.window()->findChild<QPushButton*>("TestBtn");
QObject::connect(lpTestBtn, &QPushButton::clicked, [=]() {
lpTestBtn->setText("Hi");
});
return a.exec();
}
main.pro
TEMPLATE = app
TARGET = main
QT += widgets
CONFIG += c++11
SOURCES += main.cpp
Build and Run
qmake && make && ./main
Please also note that it is bad idea to create a global pointer for a QPushButton object. It not only leaks the memory, but you could have other issues, too.
1) QApplication doesn't have a test() slot in it. You need to make your own class, inheriting QApplication, and give that class a test() slot. What you've done is create a regular function, which won't help.
2) You didn't check the return value of connect, which means you didn't see that it was giving you an error, which would probably have given you some clues.
You can connect signals to the slots which are in classes derived from QObject so meta compiler can deduce slot calls. But your test() is global function. You have to put your slot function inside a class that derives from QObject and supports Q_OBJECT macro or define a lambda function ( with C++11 support) as Laszlo Papp showed.
Example:
// testwrapper.h
class TestWrapper : public QObject
{
Q_OBJECT
//...
public slots:
void test();
};
// main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtProject w;
w.show();
QPushButton * lpTestBtn = w.window()->findChild<QPushButton*>("TestBtn");
TestWrapper tw;
CONNECT( lpTestBtn, SIGNAL( clicked()),tw,SLOT( test()));
return a.exec();
}

QSyntaxHighlighter not working for form created QTextEdit

As the title suggests, highlighting doesn't seem to work with form created QTextEdit.
My QSyntaxHighlighter derrivate class is the one from Qt docs and my code (the one that doesn't work):
ui->setupUi(this);
HtmlHighlighter hl(ui->textEdit->document());
but if I do this it works fine:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow win;
win.show();
QTextEdit editor;
HighLighter highlighter(editor.document());
editor.show();
return app.exec();
}
Is there any way to get it to work with the form generated one?
Your highlighter is going out of scope at the end of the constructor. Put it on the heap and make it a member variable, and it should work.
class MainWindow
{
//...
private:
HtmlHighlighter * h1;
}
Then in your cpp file:
ui->setupUi(this);
hl = new HtmlHighlighter(ui->textEdit->document());
Hope that helps.