How-To: Use Qt custom slots & generate Mocs in Visual Studio 2010
r3dux | April 4, 2012A while back I had a play with Qt in Linux and wrote-up how to auto-generate MOCs with a bash script… This time I needed to get Qt working in Visual Studio 2010, on machines which get wiped every time they boot, so I needed a standalone “base-project” with minimal installation requirements for students to work from. So I made one…

Project Properties
Linked below is a Visual Studio 2010 project which is an incredibly bare-bones text editor in Qt. You can enter text, you can save it (to a fixed filename), and you can quit! That’s it!
But the project does have some redeeming features in that:
- It’s completely standalone, because it comes with the required Qt headers, libs and dlls to do its thing, and
- It has a batch file that runs as a pre-build step which auto-generates the MOC files (using an included copy of moc.exe) – meaning you can change any headers in the same location as the main source and it’ll update the MOC(s) for you on build without having to dip into the commandline.
Download: 1-Standalone-Qt-Project.zip
Please note, this download is for Windows 7 64-bit, and it includes the libs/headers/dlls/moc.exe from Qt 4.8.0 (the most recent at time of writing).
If you just want the batch file to autogen the MOCs for you, then the script itself is simply:
@ECHO OFF FOR %%f IN (*.h) DO moc.exe %%f -o moc_%%~nf.cpp |
Place the batch file in the same location as your code, which is generally in the named project folder – so if I had a project called 2-QtTest, my code (and the batch file, and moc.exe) would live in 2-QtTest\2-QtTest. Finally, add executing the batch file as pre-build step like this (or just grab my project and use it as a base):

Additional
- If you want a ton of Qt functionality you might need to copy more of the Qt headers into the include folder in the project (if you have the QtSDK installed, you can find these in C:\QtSDK\Desktop\Qt\4.8.0\msvc2010\include). I only put the QtCore and QtGui folders in to keep the project size down.
- If you get a warning about being unable to delete a temporary file during build (generated by the genQtMoc batch file) – it could well be caused by AVG. For example:
PreBuildEvent: Description: Generating Qt Mocs C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(103,5): warning MSB5018: Failed to delete the temporary file "C:\Users\r3dux\AppData\Local\Temp\547660b1862d4d3491ed0d06e65f4a7a.exec.cmd". The process cannot access the file 'C:\Users\r3dux\AppData\Local\Temp\547660b1862d4d3491ed0d06e65f4a7a.exec.cmd' because it is being used by another process.
I’ve seen the error once or twice during build, but it’s not consistent – really, it’s just a tempfile being locked – shouldn’t be a concern. AVG finger-pointing source: karmiistha.
Source code after the jump for those who want it…
Main.cpp
// Include QtGui, which pulls in any other Qt related headers which we need. #include "QtGui\QtGui" // Incude our Notepad.h header so we can create an object of our custom Notepad type! #include "Notepad.h" // Pull in the main Qt libraries #pragma comment(lib, "QtMain") // QtMaind #pragma comment(lib, "QtCore4") // QtCored4 #pragma comment(lib, "QtGui4") // QtGui4 int main(int argv, char **args) { // Our QApplication instance, called "app" QApplication app(argv, args); // Create the window before you create the elements which // go inside the window! (or you'll get odd errors on exit!) QWidget window; // Create a QTextEdit object called textEdit Notepad n; // Create a layout object QVBoxLayout layout; // Add our QTextEdit and QPushButton objects to the layout layout.addWidget(&n); // Actually apply the layout to the window window.setLayout(&layout); // Set the window title window.setWindowTitle("Simple Qt Text Editor"); // Display the window window.show(); // And finally run the app! return app.exec(); } |
Notepad.h
#ifndef NOTEPAD_H #define NOTEPAD_H #include <iostream> #include <string> #include <fstream> #include "QtGui\QtGui" class Notepad : public QWidget { // Include the Q_OBJECT macro. All headers are "Moc"-ed by our genQtMoc batch file as a pre-build step Q_OBJECT public: // We'll use our own constructor and destructors Notepad(); ~Notepad(); // Each "slot" is a function we can bind to run when we click on a button private slots: void save(); // A function to save the text editor contents void quit(); // A function to quit the program private: QTextEdit *textEdit; QPushButton *saveButton; QPushButton *quitButton; QVBoxLayout *layout; }; #endif |
Notepad.cpp
#include "Notepad.h" Notepad::Notepad() { // Actually create our text editor and buttons textEdit = new QTextEdit; saveButton = new QPushButton("Save"); quitButton = new QPushButton("Quit"); // Connect our buttons to the functions we want to run when they're clicked connect( saveButton, SIGNAL( clicked() ), this, SLOT( save() ) ); connect( quitButton, SIGNAL( clicked() ), this, SLOT( quit() ) ); // Create our layout layout = new QVBoxLayout; // Add the text editor and quit button layout->addWidget(textEdit); layout->addWidget(saveButton); layout->addWidget(quitButton); // Apply the layout setLayout(layout); } // Destructor Notepad::~Notepad() { // Return resources taken by items delete quitButton; delete textEdit; delete layout; } void Notepad::quit() { std::cout << "In quit function!" << endl; exit(0); } void Notepad::save() { std::cout << "In save function!" << std::endl; // Create a file to write to called Test.txt std::ofstream ofs("Test.txt"); // Get the contents of the text field as a QString QString qs = textEdit->toPlainText(); std::string stdStringContents = qs.toUtf8().constData(); std::cout << "--------- FILE CONTENTS WILL BE ---------" << std::endl; std::cout << stdStringContents << std::endl; // Convert to a standard string and write to fileConvert the ofs << stdStringContents << std::endl; // Close the file to save it ofs.close(); } |










