I have created a gui for image acquisition. In the gui, there is a push button for image saving, and one textEdit (maybe a lineText can also be used) for receiving the input of image name defined by the user, which is to be used as the output name of the image. My question is: 1) how to get the input text of the textEdit?, and then 2) to save the image (QImage) in .jpeg format to the current directory?
# jingweimo, I had a similar problem, I hope that this solution could be suitable for your case.
For getting the input image name you only need to:
ui->labelCroppedA->setPixmap(
QPixmap::fromImage(QImage(cdir + "/" + croppedFilenamesA[croppedIndexA])));
^ add directory separator
Also for saving the image in jpeg format (or additional format) you could use a specific function QImageWriter::supportedImageFormats() which has a lot of formats you may choose from and you can see this from my previous question or below:
#include <QtWidgets>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene *scene = new QGraphicsScene;
QGraphicsView *view = new QGraphicsView{scene};
scene->addRect(QRectF(0, 0, 100, 100), QPen(Qt::red), QBrush(Qt::blue));
scene->addEllipse(QRectF(40, 30, 100, 100), QPen(Qt::green), QBrush(Qt::gray));
QComboBox *combo_formats = new QComboBox;
for(const QByteArray & format : QImageWriter::supportedImageFormats()){
combo_formats->addItem(format);
}
QPushButton *save_button = new QPushButton{"Save"};
QObject::connect(save_button, &QPushButton::clicked,[view, combo_formats](){
QPixmap pixmap = view->grab();
QString filename = QString("%1.%2").arg("image").arg(combo_formats->currentText());
pixmap.save(filename);
});
QMainWindow w;
QWidget *central_widget = new QWidget;
w.setCentralWidget(central_widget);
QFormLayout *lay = new QFormLayout{central_widget};
lay->addRow(view);
lay->addRow("Select Format:", combo_formats);
lay->addRow(save_button);
w.show();
return a.exec();
}
I hope this could be useful for your project
Related
I need help in writing my static text to image file without using "QApplication app(argc, argv);" in main(). My version of QT is 5.12.2.
Currently I'm able to do this with the below code:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QCoreApplication::addLibraryPath("./plugins");
QString imagePath(QStringLiteral("./images/output/testOutput1.png"));
QImage image(500, 400, QImage::Format_RGB888);
image.fill(Qt::red);
QPainter painter;
if (!painter.begin(&image))
return;
painter.setPen(QPen(Qt::black));
painter.setFont(QFont("Times", 12, QFont::Bold));
painter.drawText(image.rect(), Qt::AlignCenter, "writing text on image");
painter.end();
image.save(imagePath);
return 0;
}
I'm trying to get a similar type solution which does not uses "QApplication app(argc, argv);" in my code.
Currently if I remove the deceleration of "QApplication app(argc, argv);" my code crashes at "painter.drawText(...);".
The most you can do is to exchange the QApplication for a QGuiApplication (thus avoiding the useless dependency from the QtWidgets module).
Qt initializes most of its static/global stuff inside the bowels of QCoreApplication (for QtCore stuff)/QGuiApplication (for QtGui stuff)/QApplication (for QtWidgets stuff); each derives from the other, so if you have a QApplication you already have all the stuff from Gui and Core.
The font engine (and other paint-related stuff) is initialized inside the QGuiApplication constructor, as hinted in QFont documentation
Note that a QGuiApplication instance must exist before a QFont can be used.
so you are not going to paint without instantiating it (or a class derived from it).
I have inherited a virtual keyboard system with an array of buttons, one for each key. The label for each button is a single QChar. When showing the "symbols" keyboard, the code uses an '&' QChar for a key label, but the key shows as blank. I'm sure Qt is processing the '&' as a shortcut key prefix. Similarly, the entered text is shown on another, longer, button label; this label, as well, handles '&' character as an accelerator. Entering "ABC&DEF" is shown as "ABCDEF" with the 'D' underlined.
I have tried building with QT_NO_SHORTCUT #defined, but that made no difference.
Does anyone know of an easy way to disable this special handling of '&'?
The answer is found in Qt doc. QAbstractButton::text:
If the text contains an ampersand character ('&'), a shortcut is automatically created for it. The character that follows the '&' will be used as the shortcut key. Any previous shortcut will be overwritten or cleared if no shortcut is defined by the text. See the QShortcut documentation for details. To display an actual ampersand, use '&&'.
(Emphasize by me.)
QPushButton is derived from QAbstractButton inheriting this behavior.
Sample testQPushButtonAmp.cc:
#include <QtWidgets>
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
QPushButton qBtn("Text with &&");
qBtn.show();
return app.exec();
}
testQPushButtonAmp.pro:
SOURCES = testQPushButtonAmp.cc
QT = widgets
Compiled and tested on cygwin64 on Windows 10:
$ qmake-qt5 testQPushButtonAmp.pro
$ make
$ ./testQPushButtonAmp
Qt Version: 5.9.4
Concerning how to disable this default behavior:
I had a look at woboq.org QAbstractButton::setText().
void QAbstractButton::setText(const QString &text)
{
Q_D(QAbstractButton);
if (d->text == text)
return;
d->text = text;
#ifndef QT_NO_SHORTCUT
QKeySequence newMnemonic = QKeySequence::mnemonic(text);
setShortcut(newMnemonic);
#endif
d->sizeHint = QSize();
update();
updateGeometry();
#ifndef QT_NO_ACCESSIBILITY
QAccessibleEvent event(this, QAccessible::NameChanged);
QAccessible::updateAccessibility(&event);
#endif
}
So, QT_NO_SHORTCUT disables to retrieve the shortcut out of text but it has to be defined when Qt library is built from source. Actually, I'm afraid even with disabled shortcuts, the single & will still become invisible in output.
I digged deeper in woboq.org and found some promising candidates e.g.:
qt_set_sequence_auto_menmonic()
Specifies whether mnemonics for menu items, labels, etc., should be honored or not. On Windows and X11, this feature is on by default; on macOS, it is off. When this feature is off (that is, when b is false), QKeySequence::mnemonic() always returns an empty string.
Note: This function is not declared in any of Qt's header files. To use it in your application, declare the function prototype before calling it.
and a sample in QProxyStyle
#include "textedit.h"
#include <QApplication>
#include <QProxyStyle>
class MyProxyStyle : public QProxyStyle
{
public:
int styleHint(StyleHint hint, const QStyleOption *option = 0,
const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const override
{
if (hint == QStyle::SH_UnderlineShortcut)
return 0;
return QProxyStyle::styleHint(hint, option, widget, returnData);
}
};
int main(int argc, char **argv)
{
Q_INIT_RESOURCE(textedit);
QApplication a(argc, argv);
a.setStyle(new MyProxyStyle);
TextEdit mw;
mw.resize(700, 800);
mw.show();
//...
}
which I tried in my sample.
Finally, nothing of them achieved the desired effect, i.e. only "&&" was rendered as & but "&" never.
__
I have a problem with QPainter on QImage in Qt 5.4.
The image has Format_ARGB32. I want to set a given RGBA value on pixels in the image using a QPainter draw function and later read the value back using QImage::pixel.
Yet the value painted and the value read back are different. What am I doing wrong?
Sample code:
QImage image(100, 100, QImage::Format_ARGB32);
uint value = 0x44fa112b; //some value..
QPainter painter(&image);
painter.setCompositionMode(QPainter::CompositionMo de_Source);
QColor color(qRed(value), qGreen(value), qBlue(value), qAlpha(value));
QBrush brush(color);
painter.setBrush(brush);
painter.drawRect(0,0,image.width(), image.height());
uint value1 = image.pixel(50,50);
// value1 IS NOT EQUAL TO value. Why??
This works fine in Qt 5.7. Perhaps earlier Qt versions need the painter.end() call.
#include <QtGui>
int main(int argc, char ** argv) {
QGuiApplication app{argc, argv};
QImage image{100, 100, QImage::Format_ARGB32};
auto const set = 0x44fa112b;
QPainter painter(&image);
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.setBrush({{qRed(set), qGreen(set), qBlue(set), qAlpha(set)}});
painter.drawRect(image.rect());
if (false) painter.end(); //<< try with true here
auto readback = image.pixel(50,50);
qDebug() << hex << set << readback;
Q_ASSERT(readback == set);
}
Problem solved!!
Working properly when I tried with Qt 5.8
Looks like a bug with Qt 5.4.
Thanks to all :)
I am using QListWidgetItem to add Items in my QListWidget.
In some situations, I want some rows of my QListWidget become non selectable. (I mean I want some QListWidgetItem to be non selectable)
Is ther any way to do this?
PS: I tried
listWidgetItem->setFlags(Qt::NoItemFlags)
listWidgetItem->setSelected(false);
but they don't disable the selection of items.
Edit:
QStringList _strListClients = _strClients.split(",",QString::KeepEmptyParts,Qt::CaseInsensitive);
for(int i = 0; i < _strListClients.count(); i++)//Add Client's Check Boxes
{
QListWidgetItem* _listWidgetItem = new QListWidgetItem(_strListClients[i], listWidgetClients);
listWidgetClients->addItem(_listWidgetItem);
if(_strListClients[i] == "Unknown"){
_listWidgetItem->setSelected(false);
_listWidgetItem->setTextColor(Qt::red);
_listWidgetItem->setFlags(_listWidgetItem->flags() & ~Qt::ItemIsSelectable);
}
}
Just remove the Qt::ItemIsSelectable flag from each item:
item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
Or remove Qt::ItemIsEnabled if you want to remove all interaction with the item.
E.g.
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QListWidget widget;
for (int i = 0; i < 100; ++i) {
QListWidgetItem *item = new QListWidgetItem(QStringLiteral("Item %1").arg(i));
if (i % 2 == 0) // disable one every two
item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
widget.addItem(item);
}
widget.show();
return app.exec();
}
You can try the following:
1) Override the clicked/selection event (sorry I don't remember the exact name.
Doing so you can have some sort of flag/bool value on the item, and if is set as not being selectable you just return.
2) Rather then override you just connect to the signal and perform the above check and if you don't want to select that item you un-select it afterwards.
A bit of a work around but I don't know if there is a built in way to do so.
Checking the documentation I did not see a disable method on the item itself.
If you go down the road of list view you should have more control on that, also on the display, so you might be able to displayed it greyed etc. A view is a bit more work though.
M.
I'm trying to extract icon from exe file using WinAPI, but it doesn't work.
Here's the code:
QIcon OSTools::AppsInterface::extractAppIcon(const QString &fileName) const {
wchar_t *convertedName = new wchar_t[fileName.length() + 1];
fileName.toWCharArray(convertedName);
convertedName[fileName.length()] = '\0';
HICON Icon = ExtractIcon(NULL, convertedName, 0);
QPixmap pixmap = QPixmap::fromWinHICON(Icon);
return QIcon(pixmap);
}
Code outputs:
QPixmap::fromWinHICON(), failed to GetIconInfo()
(ExtractIcon function on MSDN).
I think problem is that I send NULL instead of "A handle to the instance of the application calling the function". But, generally, I use Qt, and it's only one WinAPI function in my app.
What's wrong? What's correct way to extract icon using WinAPI? If you have another function proposal, please, give me an example. This is the first time I'm using WinAPI.
UPDATE: Yes, there is a better way. You may use QFileIconProvider class for doing such things.
Works for me, even with NULL. But obtaining the HINSTANCE is actually very simple. You have a problem elsewhere i guess. Does your target exe really have an embedded icon?
#ifdef Q_WS_WIN
#include <qt_windows.h>
#endif
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
#ifdef Q_WS_WIN
QString fileName("D:\\_dev\\eclipse\\eclipse.exe");
wchar_t *convertedName = new wchar_t[fileName.length() + 1];
fileName.toWCharArray(convertedName);
convertedName[fileName.length()] = '\0';
HINSTANCE hInstance = ::GetModuleHandle(NULL);
HICON Icon = ::ExtractIcon(hInstance, convertedName, 0);
ui->label->setPixmap(QPixmap::fromWinHICON(Icon));
#endif
}
I used QFileIconProvider, and it worked perfectly. Try this :
QPushButton b;
b.show();
QIcon icon;
QFileIconProvider fileiconpr;
icon = fileIconProvider.icon(QFileInfo("/*file name*/"));
b.setIcon(icon);
// And you can also save it where you want :
QPixmap pixmap = icon.pixmap( QSize(/*desired size*/) );
pixmap.save("/Desktop/notepad-icon.png");
Source. Have a nice day.
And solution was very simple. I just sent path to '.lnk' file instead of path to file. That's my inattention.