I am getting these warning messages but I deleted the objects it warned me about. I am confused why it keeps bringing these messages up. Moreover, this is causing a bug where I have specified a signal for a push-button, but it does not do its function (I even set a debug log message if it were pressed).
in my moc_mainwindow.cpp file I noticed these lines of code:
static const qt_meta_stringdata_MainWindow_t qt_meta_stringdata_MainWindow = {
{
QT_MOC_LITERAL(0, 0, 10), // "MainWindow"
QT_MOC_LITERAL(1, 11, 22), // "on_radioButton_clicked"
QT_MOC_LITERAL(2, 34, 0), // ""
QT_MOC_LITERAL(3, 35, 26), // "on_exitRadioButton_clicked"
QT_MOC_LITERAL(4, 62, 21), // "on_pushButton_clicked"
QT_MOC_LITERAL(5, 84, 18) // "on_exitBtn_clicked"
},
"MainWindow\0on_radioButton_clicked\0\0"
"on_exitRadioButton_clicked\0"
"on_pushButton_clicked\0on_exitBtn_clicked"
};
which may have to do with the warning messages:
QMetaObject::connectSlotsByName: No matching signal for on_radioButton_clicked()
QMetaObject::connectSlotsByName: No matching signal for on_exitRadioButton_clicked()
QMetaObject::connectSlotsByName: No matching signal for on_pushButton_clicked()
any help is gladly appreciated :)
You need to delete the build folder (the whole thing), and build the project again. I suggest a switch to cmake with Ninja - it won’t have such problems.
You have obsolete signal/slot connections in UI files - the .ui.h headers are where connectSlotsByName is invoked. So simply Greg your entire source folder for the names of the signals (Ctrl-Shift-F in Qt Creator), include all file types, and you’ll likely find those names inside the connections element in the .ui Xml files. They can be removed from there manually, or using the Designer built into Qt Creator.
Deleting the build folder is the starting point - you can’t afford to have any old state, and the “Clean” option in the IDE doesn’t do that last time I checked.
So after some digging around I found the issue. It seems that it doesn't delete the slots which are located in the 'mainwindow.h' file. I need to delete these:
After running the application again, it then removes 'QT_MOC_LITERAL' that aren't being used (i.e deleted UI elements) as mentioned above (in the question) in the 'moc_mainwindow.cpp' file.
Related
I am trying to watch the changes in a directory using QFileSystemModel. Whenever I rename a file in the root path, only the directoryLoaded() signal is emitted. I want the fileRenamed() signal to be emitted so that I know which file is renamed to a new name. Here is my code:
model = new QFileSystemModel;
model->setRootPath("C:/test/");
QObject::connect(model, SIGNAL(fileRenamed(const QString&, const QString&, const QString&)), this, SLOT(updateRename()));
QObject::connect(model, SIGNAL(directoryLoaded(const QString&)), this, SLOT(loadDir()));
I am afraid you expect too much from this QFileSystemModel class. It does not and cannot catch if the renaming operation happens outside of the model. I looked up all uses of fileRenamed() signal and it seems that the only place where it is emitted is here: https://code.woboq.org/qt5/qtbase/src/widgets/dialogs/qfilesystemmodel.cpp.html#933
And if you go a few lines above, you can see that this is triggered when the renaming happens inside this function https://code.woboq.org/qt5/qtbase/src/widgets/dialogs/qfilesystemmodel.cpp.html#873 In other words, if you use QFileSystemModel::setData() to set a name to an item, it will rename the item and emit the signal. And it is the only way to have the signal emitted.
And this is logical, if renaming happens outside of your program, then there is no certain way to find out that a certain file was renamed. Your application only observes that some file disappeared and another file with a different name emerged. Of course, you can check whether the timestamp and size of the file is the same, whether they are also in the same parent folder, maybe also check the file content... and only if these things match and the only difference is in the file names, then you can conclude that the file was renamed. But this is something you must program yourself. QFileSystemModel will not do it for you because it does not know your specific intentions.
I've been trying to make a simple wxWidgets program with just a button with a picture on it. I've been able to make the button with the image on it easily enough, but my problem arises when including it.
So far, I've only been able to fetch the image during run-time (the image has to be in the same folder as the .exe file; otherwise, I get error 2: the system cannot find the file specified). With this method, I have no problems -- the program works just fine. What I'm trying to do, however, is to #include the file so that it is embedded during compile-time, so that it doesn't need to be available during run-time.
I've tried #including the file (both as .png and as .xpm), and I've also tried adding it to the resource includes (this is on Visual Studio 2017). Neither of these worked -- the first method still required the image to be in the same folder, and the second failed during compilation (as far as I can tell, it wasn't able to read the .xpm file).
Here is the relevant code, if it helps:
/*relevant includes*/
#include "happyFace.png" //this isn't working. the file is still needed
||
#include "happyFace.xpm" //ditto
/*I have also tried putting these lines in the resource includes.*/
/*code*/
wxInitAllImageHandlers();
wxBitmap bitmap("happyFace.xpm", wxBITMAP_TYPE_XPM); //only works in same directory at run-time
||
wxBitmap bitmap("happyFace.png", wxBITMAP_TYPE_PNG); //ditto
wxButton *button = new wxButton(this, ID_BMP_BUTTON);
button->SetBitmap(bitmap);
//the rest of the button programming and stuff
Sorry if I haven't provided enough information; I can provide more if necessary. I would really appreciate any help. Thanks!
Two possibilities... Number 1 is simplest. It's been a long time since I wrote the code I'm looking at, so the details are fuzzy.
In Visual Studio, Solution Explorer, add the image into the resource files. Assume the name of the resourse is sample.rc. Then it can be used like so to set the main icon...
SetIcon(wxICON(sample));
Method 1 must be used in order for MS Windows Explorer to display the main icon. I do not remember how to use .rc resources for other things, but it should be easy to figure out.
I did it this way before I discovered VS resource (.rc) files. Compile the file-image into the program "by hand." In other words, write a program that will read an image file and produce bit-for-bit copy in a .cpp file. Then compile that .cpp into the program. Here I have the file-image in memory as an object named dj::main_cursor. Note that the in-memory version is a bit-for-bit copy of a .cur file.
dj::captured_file &c1file(dj::main_cursor);
wxMemoryInputStream cistr(c1file.contents, c1file.size);
cursor1 = wxCursor(wxImage(cistr, wxBITMAP_TYPE_CUR));
FYI, I defined the structure dj::captured_file like so:
struct captured_file {
const char *name;
const unsigned long size;
const void *contents;
captured_file(const char*fn, size_t sz, const void*c)
: name(fn)
, contents(c)
, size(sz)
{}
};
See also, Embedding PNG Images into Windows RC Files
I found some other documentation.
Resources and Application Icon All applications using wxMSW should
have a Windows resource file (.rc extension) and this file should
include include/wx/msw/wx.rc file which defines resources used by
wxWidgets itself.
Among other things, wx.rc defines some standard icons, all of which
have names starting with the "wx" prefix. This normally ensures that
any icons defined in the application's own resource file come before
them in alphabetical order which is important because Explorer
(Windows shell) selects the first icon in alphabetical order to use as
the application icon which is displayed when viewing its file in the
file manager. So if all the icons defined in your application start
with "x", "y" or "z", they won't be used by Explorer. To avoid this,
ensure that the icon which is meant to be used as the main application
icon has a name preceding "wxICON" in alphabetical order.
http://docs.wxwidgets.org/3.1.0/page_port.html
Here is how you should do it:
#include "happyFace.xpm"
wxBitmap bitmap = wxBitmap( happyFace ); // assuming the variable name is "happyFace" inside the xpm
Then you will use bitmap object just like usual. Assuming that the file happyFace.xpm is available for compilation.
I'm pretty new to QT so maybe the answer to this question is simple. I'm making a terminal for our freescale car this year which is just a car that autonomously goes around a track. We're using line-scan cameras which give you a line of data 128 pixels long that you refine into either "white" or "black" (edges of the track) values. Last year the team made this terminal in QT which is used for modifying certain coefficients, stopping the motors, and all kinds of stuff through bluetooth. A text browser was used to display what the line cameras see.
Last year they combined the two cameras to create one image, but we're re configuring them this year, and they will produce two different images of the track. Naturally, I need to make two text browsers, one for each camera. Should simply be a case of copying code and changing some names right? Well apparently not.
I placed the text browser in the window using the design gui, named it, and made its settings match the other browser. I went into the code for the main window c file and adapted the code there. For every reference to the other browser I made sure one was an equal line of code for this one. When I was done and went to build the project, it told me that the browser wasn't a member of 'UI::MainWindow,' and pointed me to the ui_mainwindow.h file. So I went into that header and did the same thing in there. But when I built that, it gave me the error:
...\ui_mainwindow.h:1363: error: C2065: 'tb_camera_out_close' : undeclared identifier
How can that be? There doesn't appear to be any other reference to the other text browser and it works fine. How do I go about declaring this? Shouldn't the gui interface have done it for me when I placed it?
Here's the code from the main window's C file that is involved:
ui->tb_camera_out->setText(msgs_received[1] + '\n' + ui->tb_camera_out->toPlainText());
ui->tb_camera_out_close->setText(msgs_received[2] + '\n' + ui->tb_camera_out_close->toPlainText());
tb_camera_out is the old camera code(I am aware that the toplaintext() part won't work, I'm also attempting to get the text to scroll down instead of up like a track would if you were actually driving but I need to fix this major issue first)
Here's the code from the header that I added:
tb_camera_out = new QTextBrowser(centralWidget);
tb_camera_out->setObjectName(QStringLiteral("tb_camera_out"));
sizePolicy.setHeightForWidth(tb_camera_out->sizePolicy().hasHeightForWidth());
tb_camera_out->setSizePolicy(sizePolicy);
tb_camera_out->setMinimumSize(QSize(450, 0));
tb_camera_out->setMaximumSize(QSize(16777215, 16777215));
tb_camera_out->setStyleSheet(QLatin1String("background-color: rgb(0, 0, 0);\n" "color: rgb(31, 234, 0);"));
gridLayout_4->addWidget(tb_camera_out, 1, 0, 1, 5);
tb_camera_out_close = new QTextBrowser(centralWidget);
tb_camera_out_close->setObjectName(QStringLiteral("tb_camera_out_close"));
sizePolicy.setHeightForWidth(tb_camera_out_close->sizePolicy().hasHeightForWidth());
tb_camera_out_close->setSizePolicy(sizePolicy);
tb_camera_out_close->setMinimumSize(QSize(450, 0));
tb_camera_out_close->setMaximumSize(QSize(16777215, 16777215));
tb_camera_out_close->setStyleSheet(QLatin1String("background-color: rgb(0, 0, 0);\n" "color: rgb(31, 234, 0);"));
Again, the old code is at the top with the references to tb_camera_out. The stuff I added is associated with tb_camera_out_close.
I seem to have solved the problem. Strangely enough, to fix the errors that were showing up I not only had to edit that header, but I then had to delete it and run qmake to restore it. I then had to delete all the past builds to get the thing to even show up when I ran it.
I have a class that inherits from QFileDialog. In the constructor, I call setDirectory and pass in the last directory visited (which the class keeps track of; see code below). On Windows, this works fine. And if I show the dialog multiple times, it is internally smart enough to resume at the last location (e.g. where the user saved a file before). This is the desired behavior.
On Ubuntu 12.04 (GCC 4.8 compiler), on the other hand, the system does not automatically resume where last left off if I call showFileDialog multiple times. So I tried adding the setDirectory call within that function as commented below, but that didn't change anything. Furthermore, if I take out setDirectory from the constructor so it is only called in showFileDialog, the file dialog opens to the folder from which the program was run. (i.e. setDirectory didn't work.) Subsequent calls to showFileDialog will open a file dialog starting in the directory requested.
So it seems like the call has a delayed effectiveness. Is this a Qt bug, or mine? Either way, how can I get the setDirectory call to be effective?
Example code:
QString FileDialog::defaultDir = QDir::homePath();
FileDialog::FileDialog(QWidget *parentWindow /*, ...*/)
: QFileDialog(parentWindow)
{
setDirectory(defaultDir);
//...
}
QString FileDialog::showFileDialog()
{
// Adding setDirectory(defaultDir) here doesn't help.
if(!exec())
{
return QString::null;
}
defaultDir = directory().path();
//...
}
It is not clear from the code above how you know that the path was changed. I'm not sure that directory() is responsible for that.
Consider using void QFileDialog::directoryEntered(const QString & directory) signal.
Workaround found:
I happen to set the dialog title (setWindowTitle()) every time I open a FileDialog. If I connect to the QFileDialog::windowTitleChanged signal and call setDirectory within the slot, it is effective.
This is an unintuitive workaround though, so I am open to better answers.
I'm developing an app on windows with Qt and I need to detect changes in a specific folder.
So I used a QFileSystemWatcher, and I connect the directoryChanged signal to a function that will send a message in case of changes.
The problem is that the "slot" function connected to directoryChanged is not called if I modify a file's content, but only when a file or directory is removed or added.
However, the documentation says that this signal is emitted when "the directory at a specified path, is modified (e.g., when a file is added, modified or deleted) or removed from disk."
Does anyone have an explanation?
Thanks in advance =)
According to Qt source code version 4.8.2, as following:
void QFileSystemWatcherPrivate::_q_directoryChanged(const QString &path, bool removed)
{
Q_Q(QFileSystemWatcher);
if (!directories.contains(path)) {
// perhaps the path was removed after a change was detected, but before we delivered the signal
return;
}
if (removed)
directories.removeAll(path);
emit q->directoryChanged(path);
}
It seems that directoryChanged emit when a file removed, added(for the new added file not contains in directories), and renamed. The implementation does not guarantee to detect a modification of a file's content. Hope that helps :P