Thursday, March 29, 2012

Shape QPushButton in your own style Qt

                           Have you ever tried to create your own QPushButton shaped as you like? For example, Have you tried to create a 'L' shaped button or like a 'Enter' shaped button in your keyboad so visualize your software with a unique style? WPF in windows provides a lot of flexibility but it is having its own draw backs. Here Qt is providing flexibility of shaping button as you wish. Masking the shape of a image file, will help you to attain the button as you wish. Lets see the basics how we can do it.


class QMPButton : public QPushButton
{
  Q_OBJECT
  QSize imagesize;
public:
  explicit QMPButton(const QString &_shape,QObject *parent = 0);
signals:
public slots:
};

Here QMPButton is inherited from QPushButton, So We can get properties of QPushButton where ever you are using Object of QMPButton. QMPButton::_shape is the file name of image which we need the shape to be masked with.
 
QMPButton::QMPButton(const QString &_shape,QObject *parent) :  

QPushButton((QPushButton*)parent)

{

  QPixmap pixmap(_shape);

  imagesize = pixmap.size();

  this->setFixedSize(imagesize);

  this->setMask(pixmap.mask());

}

This Initialize and shape the button and fix it where ever you want.
Usage:


QMPButton *mbtton = new QMPButton(ui->lineEdit->text(), NULL);
  mbtton->setText("Ok");

  ui->gridLayout->addWidget(mbtton);


You can customize more by introducing style sheets and images for mouse hover, clicks etc. If you have images according to that shape will suite it more and you can now make unique style for your applications.
As like :

mbtton->setStyleSheet(QString:: 
fromUtf8("QPushButton{border-image: url(:res/pc-enter.png);}\n"
"QPushButton:hover{border-image: url(:res/pc-enter1.png);}\n"
"QPushButton:pressed{border-image: url(:res/pc-enter2.png);}"));

The Point am projecting you is that, button will be active only on the regions of the image not as a whole rectangle!

Output tested in X11 and also in Wayland:



Queries are welcome !

Wednesday, March 28, 2012

Base Thread Class available for your Customization


          I have wandered through many sites to implement thread class, which can be used as generic thread class for specific reuse and user specified thread functions. But I failed to find a class which provide the flexibility (there are many 3rd party thread libraries but implementation is wired and little complicated to use ). But QThread in QT4 framework is more easy and reliable to use. So here Am explaining how to Implement a thread class like QThread. I didn't meant QThread was written in the manner described below but this class can be used similar to a QThread class.
You are familiar with pthread_create(), pthread_join(), pthread_exit() etc Check it here . Normally you need to pass the thread Id, thread attributes, function pointer and arguments as void pointer in to  POSIX thread create function . Am Using Basic thread as POSIX thread itself, for create join etc etc.

class mPthread
{
public:
    mPthread(); // Plain constructor but you can provide arguments if necessary
    pthread_t threadId; //Common Pthread ID for single instance will help you to save ur face.
    pthread_attr_t threadAttr; // if needed
    virtual void run(); // this is a base class means it can be inherited and run() can be redefined.
    void start(); //key function for the thread call.
private:
    static void *mThreadFunction(void *arg); //this is the function pointer passing in to pthread_create().
};

/*this function can be re-implemented in its child class */

void mPthread::run()
{
    for(int i=0; i<10;i++)
    {
        cout<<": In Base Class :"<<endl;
        sleep(1);
    }
}
/*this function will start the thread from the user call.*/
void mPthread::start()
{
    pthread_attr_t      attr;
    pthread_attr_init(&attr);
    int ret = pthread_create(&threadId,&attr,mThreadFunction,this);
    cout<<"ret thread:"<<ret<<endl;
}
/*this is the pthread function pointer*/
void *mPthread::mThreadFunction(void *arg)
{
    m_this = arg;
    mPthread* thisObj = (mPthread*)arg;
    thisObj->is_running = true;
    thisObj->run();
    thisObj->is_running = false;
    return NULL;
}

The base class having a start function which will help you to start the thread. If you want to use this class you just need to simply inherit it in your own class to handle the thread. sample implementation is given below.

class threads : public mPthread
{
public:
    threads();
    void run();//this is the run() function with the provision to be redefined. :)
};
void threads::run()
{
    for(int i=0; i<10;i++)
    {
        cout<<":User Run:"<<endl;
        sleep(1);
    }
}
int main()
{
 threads *th = new threads();
 th->start(); // this start will help you to start the thread. out put will be your run function.
}
output:
:User Run:
:User Run:
:User Run:
:User Run:
:User Run:
:User Run:
:User Run:
:User Run:
:User Run:
:User Run:

If run function is not implimented in inherited class, then output will be .
: In Base Class :
: In Base Class :
: In Base Class :
: In Base Class :
: In Base Class :
: In Base Class :
: In Base Class :
: In Base Class :
: In Base Class :
: In Base Class :


Extra features like Thread detach , exit etc can also implement in the base class, be careful in using the common class object thread_id for all the above purpose.
Feel free to ask here, for any more explanation.



Windows Package & deployment


Windows Package & deployment
It is just an out line how we can create a setup package using Microsoft visual studio 2008. I am just trying to create a MSI - a windows installing package for a particular executable. So from the beginning iam trying to explain with screen-shots.
I : Get your executable (eg: BuisnessPjt.exe) and open this in dependency walker (http://www.dependencywalker.com/). This will help you to trace out which all *.dll files are needed for the executable to work. Avoid System files from the list and copy all the third party dll files to a folder along with the executable. If the executable work just by double clicking on it, then you have got 99% dlls needed for the executable to work stand alone.



II : Now its the time to create a setup (Microsoft installation package- MSI  )
1) Microsoft visual studio 2008 Open>>File>>New Project . This will help you to create a MSI package. You can give your specified path & create Solution.

2) Under the MSI Solution You will get
* Application Folder: Here under this you need to add files needed for the packaging. Executable, dlls, Icons, Readme.txt etc like what ever you want to come under program files (programfiles/testapplication )folder.
* Users's Desktop : You can provide links in this folder to the installed program in programs file folder @ desktop.
* User's Program menu: You can provide links in this folder to the installed program in programs file folder @ Start>>Program menu.
 So add files to Application Folder.


2) Add all files including executables and dlls from the folder as like given in first picture. Create a link or short cut for the exe and drag and drop to User's Desktop and Users Program menu.

3) Created Short cut and dragged to Users Desktop.


4) You can Set Icon for the desktop Short cut. Set it from its property window at right side.

5)Build the solution.



*** After creation of Set Up package, its installation 
 



Any more Doubts or suggestions feel free to ask here. Adding pages or for your custom Installation interface, try for 3rd Party MSI packaging applications  eg: http://www.purepackaging.com/ but you can also Introduce DLLs embedded in its way of installation.